使用Entity保存@IdClass时出错

时间:2017-12-01 15:05:36

标签: hibernate jpa spring-data-jpa many-to-one composite-primary-key

我创建了一个具有如下所示的复合ID的实体:

@Entity
@IdClass(CompId.class)
public class CompEntity {

    @Id
    @ManyToOne(optional = false)
    private AccountEntity account;

    @Id
    @ManyToOne(optional = false)
    private ProductEntity product;
...
}

CompId看起来像这样:

public class CompId implements Serializable {

    private Long account;

    private Long product;
}

帐户和产品都使用自动生成的简单Long ID。

在单元测试中,一切正常。在运行服务器中,当我尝试保存新的CompEntity时,我收到以下错误:

org.springframework.dao.InvalidDataAccessApiUsageException: Can not set java.lang.Long field CompId.product to ProductEntity_$$_jvstd2f_36; nested exception is java.lang.IllegalArgumentException: Can not set java.lang.Long field CompId.product to ProductEntity_$$_jvstd2f_36

据我了解jpa和在线示例,这应该有用,所以我不知道出了什么问题。

我很感激任何建议。

EDIT1:

以下是ProductEntity和AccountEntity

@Entity
public class AccountEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
...
}

@Entity
public class ProductEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
...
}

编辑2:

CompEntity的存储库

public interface CompRepository extends JpaRepository<CompEntity, CompId> {
...
}

2 个答案:

答案 0 :(得分:0)

您需要在关系上使用@JoinColumn来指定要在该实体中引用的列。

    @Entity
    @IdClass(CompId.class)
    public class CompEntity {

        @Id
        @ManyToOne(optional = false)
        @JoinColumn(name = "account_id")
        private AccountEntity account;

        @Id
        @ManyToOne(optional = false)
        @JoinColumn(name = "product_id")
        private ProductEntity product;
    }

答案 1 :(得分:0)

@IdClass用于在休眠实体中创建组合键。

单身父母

如果父类具有单个键,则在子对象的@IdClass中使用单个键的数据类型。

示例:

//Parent
@Entity
@Table(name = "GROUP")
public class Group implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "GROUP_ID")
    private Long groupId;

    ...
}

//Child
@Entity
@Table(name = "RECORD")
@IdClass(RecordId.class)
public class Record implements Serializable {

    @Id
    @Column(name = "FIELD_ID")
    private Long fieldId;

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="GROUP_ID") //Join Column is just for naming purposes
    private Group group;

    ...
}

//Composite Id for Record
public class RecordId implements Serializable {

    private Long fieldId;

    //Use the @Id datatype from Group
    private Long group;

    //Getters, Setters, and Constructor omitted for space
}

综合ID父级

如果父类具有复合Id类,则将复合Id类用作子对象@IdClass中的数据类型。

示例:

    //Parent
@Entity
@Table(name = "GROUP")
@IdClass(GroupId.class)
public class Group implements Serializable {

    @Id
    @Column(name = "GROUP_ID")
    private Long groupId;

    @Id
    @Column(name = "GROUP_NAME")
    private String groupName

    ...
}

//Composite Id for Group
public class GroupId implements Serializable {

    private Long groupId;

    //Use the @Id datatype from Group
    private String groupName;

    //Getters, Setters, and Constructor omitted for space
}



//Child
@Entity
@Table(name = "RECORD")
@IdClass(RecordId.class)
public class Record implements Serializable {

    @Id
    @Column(name = "FIELD_ID")
    private Long fieldId;


    /*
    * JoinColumns is just used for naming columns:
    *    -(name) indicates the column to create in this table Record
    *    -(referencedColumnName) indicates the corresponding column in the parent Group
    */
    @Id
    @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumns({
        @JoinColumn(name="GROUP_ID", referencedColumnName="GROUP_ID"),
        @JoinColumn(name="GROUP_NAME", referencedColumnName="GROUP_NAME")
    })
    private Group group;

    ...
}

//Composite Id for Record
public class RecordId implements Serializable {

    private Long fieldId;

    //Use the @IdClass for the datatype because the parent has a composite key.
    private GroupId group;

    //Getters, Setters, and Constructor omitted for space
}

我投入了赏金,发现我没有在孩子的@IdClass中为父母使用正确的数据类型。我在此答案中加入了创建@IdClass的规则,希望对其他人有所帮助。

P.S。

我最初创建的@IdClass错误,是前几天我头痛的原因。

    //Composite Id for Record
    public class RecordId implements Serializable {

        private Long fieldId;

        /*
         * WRONG WAY
         * 
         * The cause of my error was due to the wrong dataype being used in this child 
@IdClass.
         */
        private Group group;

        //Getters, Setters, and Constructor omitted for space
    }