简体   繁体   English

使用@Embedded和@Id的Hibernate复合主键

[英]Hibernate composite primary key using @Embedded and @Id

I wanted to find out if hibernate supports composite primary key using a field and a component type. 我想知道hibernate是否支持使用字段和组件类型的复合主键。 So I have an @Embeddable component type and I would like to use it as a primary key along with another column as a composite primary key. 所以我有一个@Embeddable组件类型,我想将它作为主键与另一列作为复合主键使用。

So my table "DEPT_HISTORY" has composite primary keys (GROUP_DEPT, DEPTID, EFFDT). 所以我的表“DEPT_HISTORY”有复合主键(GROUP_DEPT,DEPTID,EFFDT)。 I mapped GROUP_DEPT and DEPTID as an @Embeddable component type to Department class. 我将GROUP_DEPT和DEPTID作为@Embeddable组件类型映射到Department类。

@Embeddable public class Department implements Serializable {

    private static final long serialVersionUID = 1L;

    private String departmentGroup;

    private String departmentId;

    public String getDepartmentGroup() {
        return departmentGroup;
    }

    public void setDepartmentGroup(String departmentGroup) {
        this.departmentGroup = departmentGroup;
    }

    public Department withDepartmentGroup(String departmentGroup) {
        setDepartmentGroup(departmentGroup);
        return this;
    }

    public String getDepartmentId() {
        return departmentId;
    }

    public void setDepartmentId(String departmentId) {
        this.departmentId = departmentId;
    }

    public Department withDepartmentId(String departmentId) {
        setDepartmentId(departmentId);
        return this;
    }

    @Override
    public String toString() {
        return Objects.toStringHelper(this).add("departmentGroup", getDepartmentGroup())
                .add("departmentId", getDepartmentId()).toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Department)) {
            return false;
        }
        Department other = (Department) obj;

        return Objects.equal(getDepartmentGroup(), other.getDepartmentGroup())
                && Objects.equal(getDepartmentId(), other.getDepartmentId());

    }

    @Override
    public int hashCode() {
        return Objects.hashCode(getDepartmentGroup(), getDepartmentId());
    }

}

I am mapping a composite primary key using GROUP_DEPT, DEPTID above and EFFDT below as follows. 我正在使用GROUP_DEPT,DEPTID以及EFFDT映射复合主键,如下所示。 Does hibernate support this. 休眠是否支持这一点。 I have similar classes that it works on but for some reason fails on this class with "Caused by: org.hibernate.AnnotationException: com.blah.blah.component.Department must not have @Id properties when used as an @EmbeddedId: com.blah.blah.entity.DepartmentHistory.department 我有类似的类,但它出于某种原因在这个类上失败了“引起:org.hibernate.AnnotationException:com.blah.blah.component.Department在用作@EmbeddedId时不能有@Id属性:com .blah.blah.entity.DepartmentHistory.department

@Entity @Table(name = "dept_history") public class DepartmentHistory implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final String DATETIME_FORMAT = "MM-dd-yyyy HH:mm:ss ZZ";
    protected static final DateTimeFormatter DATE_FORMAT = DateTimeFormat.forPattern(DATETIME_FORMAT);

    @Id
    @Embedded
    @AttributeOverrides({
            @AttributeOverride(name = "departmentGroup", column = @Column(name = "GROUP_DEPT", nullable = false)),
            @AttributeOverride(name = "departmentId", column = @Column(name = "DEPTID", nullable = false)) })
    private Department department;

    @Id
    @Column(name = "EFFDT", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar effectiveDate;

    @Column(name = "DESCR", nullable = false)
    private String description;

    @Column(name = "MANAGER_ID", nullable = false)
    private String managerId;

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(final Department department) {
        this.department = department;
    }

    public DepartmentHistory withDepartment(final Department department) {
        setDepartment(department);
        return this;
    }

    public Calendar getEffectiveDate() {
        return effectiveDate;
    }

    public void setEffectiveDate(final Calendar effectiveDate) {
        this.effectiveDate = effectiveDate;
    }

    public DepartmentHistory withEffectiveDate(final Calendar effectiveDate) {
        setEffectiveDate(effectiveDate);
        return this;
    }

    public DateTime readEffectiveDateAsDateTime() {
        return calendarToDateTime(effectiveDate);
    }

    public void writeEffectiveDateAsDateTime(final DateTime effectiveDate) {
        this.effectiveDate = dateTimeToCalendar(effectiveDate);
    }

    public DepartmentHistory withEffectiveDateAsDateTime(final DateTime effectiveDate) {
        writeEffectiveDateAsDateTime(effectiveDate);
        return this;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(final String description) {
        this.description = description;
    }

    public DepartmentHistory withDescription(final String description) {
        setDescription(description);
        return this;
    }

    public String getManagerId() {
        return managerId;
    }

    public void setManagerId(final String managerId) {
        this.managerId = managerId;
    }

    public DepartmentHistory withManagerId(final String managerId) {
        setManagerId(managerId);
        return this;
    }

    @Override
    public String toString() {
        return Objects.toStringHelper(this).add("department", getDepartment())
                .add("effectiveDate", DATE_FORMAT.print(readEffectiveDateAsDateTime()))
                .add("description", getDescription()).add("managerId", getManagerId()).toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof DepartmentHistory)) {
            return false;
        }
        DepartmentHistory other = (DepartmentHistory) obj;

        return Objects.equal(getDepartment(), other.getDepartment())
                && Objects.equal(getEffectiveDate(), other.getEffectiveDate());

    }

    @Override
    public int hashCode() {
        return Objects.hashCode(getDepartment(), getEffectiveDate());
    }

}

Can I combine an @Embeddable and another field into a composite primary key using @Id property on the @Embedded and field. 我是否可以使用@Embedded和字段上的@Id属性将@Embeddable和另一个字段组合成复合主键。 I don't want to make (GROUP_DEPT, DEPTID, EFFDT) as an @EmbeddedId because such a component type does not make sense and I don't want to create a class that does not mean anything in my domain just to use as a composite primary key. 我不想将(GROUP_DEPT,DEPTID,EFFDT)作为@EmbeddedId,因为这样的组件类型没有意义,我不想创建一个在我的域中没有任何意义的类只是用作复合主键。 A component Department containing just (GROUP_DEPT, DEPTID) makes sense as a department. 仅包含(GROUP_DEPT,DEPTID)的组件部门作为一个部门是有意义的。 Thanks much. 非常感谢。

As per the spec you should use and @EmbeddedId or @IdClass when you use composite key. 根据您使用复合键时应使用的规范和@EmbeddedId或@IdClass。

If the dependent entity class has primary key attributes in addition to those corresponding to the parent's primary key or if the parent has a composite primary key, an embedded id or id class must be used to specify the primary key of the dependent entity. 如果从属实体类除了与父主键对应的主键属性之外还具有主键属性,或者父节点具有复合主键,则必须使用嵌入式id或id类来指定从属实体的主键。 It is not necessary that parent entity and dependent entity both use embedded ids or both use id classes to represent composite primary keys when the parent has a composite key. 当父组件具有复合键时,父实体和从属实体都不必使用嵌入式ID或两者都使用id类来表示复合主键。

Question was: 问题是:

I am mapping a composite primary key using GROUP_DEPT, DEPTID above and EFFDT below as follows. 我正在使用GROUP_DEPT,DEPTID以及EFFDT映射复合主键,如下所示。 Does hibernate support this.? 休眠是否支持这一点。

Yes hibernate support that, but you should use @EmbeddedId, I know that this need to create a new class to handle the key but that need to be done as far as I know. 是的,hibernate支持,但你应该使用@EmbeddedId,我知道这需要创建一个新类来处理密钥,但据我所知,这需要完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM