簡體   English   中英

Hibernate 一對多只獲取目標實體的主鍵列

[英]Hibernate one-to-many to fetch only primary key column of the target entity

我有以下兩個 JPA 實體:遵循一對多關系的公司和員工:

Employee
---------
eId  |  eName   | company_id

Company
--------
cId  |  cName

我一直在嘗試獲取公司實體中的員工 ID 列表。 我嘗試了兩種方法 - employees1 和 employees2 如下所示。 兩者都不工作 請注意,我想要的是員工 ID 列表,而不是員工列表。

@Entity
public class Employee {
   @Id
   String eId;
   String eName;
}

@Entity
public class Company{
   @Id
   String cId;
   String cName;

   // both of the below are not working
   
   @OneToMany(fetch = EAGER, targtEntity = Employee.class )
   @JoinColumn(name = "company_id", referencedColumn = "cId")
   @Column(name = "eId")
   Set<String> employees1 = new HashSet<>();
   

   @OneToMany(fetch = EAGER)
   @JoinColumn(name = "company_id", tableName = "Employee", referencedColumn = "cId")
   @Column(name = "eId")
   Set<String> employees2 = new HashSet<>();
}

對於 employees1,我得到:org.hibernate.property.access.spi.PropertyAccessException:訪問字段時出錯。

對於 employees2:org.hibernate.cfg.NotYetImplementedException:Collections 在輔助表中有 FK。

請幫忙!

查看Vlad Mihalcea 的這篇文章,它非常詳細地解釋了所有內容:最佳映射如下所示:

@Entity
public class Employee {

    @Id
    private String eId;

    private String eName;

    @ManyToOne(fetch = FetchType.LAZY)
    private Company refundRequest;

    void setRefundRequest(Company refundRequest) {
        this.refundRequest = refundRequest;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return Objects.equals(eId, employee.eId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(eId);
    }
    
}
@Entity
public class Company {

    @Id
    private String cId;

    private String cName;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "company", orphanRemoval = true)
    private List<Employee> employees;

    public void addEmployee(final Employee employee) {
        employee.setRefundRequest(this);
        employees.add(employee);
    }
    
    public void removeEmployee(final Employee employee) {
        employee.setRefundRequest(null);
        employees.remove(employee);
    }
    
}

請務必閱讀上面提到的文章以了解為什么此映射是最佳的!

為了獲取它,您可以使用存儲庫:

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, String> {

    @Query("select e.eId from Employee e where e.company = :company")
    List<String> findEmployeeIdsByCompany(@Param("company") Company company);

}

順便說一下,eager fetching 是一種巨大的代碼味道,應該避免!

@ElementCollection是您在這種情況下需要使用的注釋。 @CollectionTable定義您要從哪個表中獲取值以及連接發生在哪個列上。 @Column定義要從@CollectionTable中獲取的列名

@Entity
class Company {
    @Id
    String cId;
    String cName;

    @ElementCollection
    @CollectionTable(name = "Employee", joinColumns = @JoinColumn(name = "company_id"))
    @Column(name = "eId")
    Set<String> employeeIds = new HashSet();

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM