hibernate - JPA 2.0 - 在父实体上自动持久化子实体持久化,给出 org.hibernate.id.IdentifierGenerationException

标签 hibernate jpa-2.0

我有两个实体,名为 Customer 和他的 Biling Address。关系是一对一的。每个客户都有一个账单地址。 我想在保留客户时自动保留帐单地址。 客户 ID 是客户实体的主键,也是地址实体中的主键和外键。

//parent table
public class CustomerDTO implements Serializable {

@Id
@GeneratedValue
@Column(name = "customer_id")
private Integer id;

@OneToOne(fetch=FetchType.LAZY,cascade=CascadeType.ALL )
@PrimaryKeyJoinColumn(name="customer_id")
BillingAddressDTO billingAddressDTO;



//child table
public class BillingAddressDTO implements Serializable {
@Id
@Column(name="customer_id")
private Integer id;

这是我用来持久化实体的代码

    customerDTO = new CustomerDTO();
    customerDTO.setFirstName(firstName);

    billingAddressDTO = new BillingAddressDTO();
    billingAddressDTO.setBillingAddress(address1);
    customerDTO.setBillingAddressDTO(billingAddressDTO);
   //persisting customer entity
   customerDAO.persist(customerDTO);

我遇到异常

  Caused by: org.hibernate.id.IdentifierGenerationException: ids for this   
  class must be manually assigned before calling save():

我想将相同的客户 ID 分配给地址表,所以我不想手动分配它。感谢您的宝贵时间。

最佳答案

您需要的是所谓的派生标识符。在这种方法中,CustomerDTO(父实体)的主键与 BillingAddressDTO(从属实体)共享。

@Entity
public class CustomerDTO implements Serializable {
    @Id
    @GeneratedValue
    @Column(name = "customer_id")
    private Integer id;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn(name = "customer_id")
    private BillingAddressDTO billingAddressDTO;
    ...
}
@Entity
public class BillingAddressDTO implements Serializable {
    @Id
    private Integer id; // @Column is NOT allowed since id is indicated by @MapsId

    @MapsId
    @OneToOne(mappedBy = "billingAddressDTO")
    @JoinColumn(name = "customer_id")
    private CustomerDTO customerDTO;
    ...
}

在上面的场景中,父实体 CustomerDTO 有一个简单的主键 customer_id 并且从属实体 BillingAddressDTO 共享一个主键属性由关系属性 customerDTO 映射。


更新:基于阿里评论的替代解决方案,以避免双向关系

@Entity
public class CustomerDTO implements Serializable {
    @Id
    private Integer id;

    @MapsId
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "customer_id")
    private BillingAddressDTO billingAddressDTO;
    ...
}
@Entity
public class BillingAddressDTO implements Serializable {
    @Id
    @GeneratedValue
    @Column(name = "customer_id")
    private Integer id;
    ...
}

在上面的场景中,父实体 BillingAddressDTO 有一个简单的主键 customer_id 并且从属实体 CustomerDTO 共享单个主键属性由关系属性 billingAddressDTO 映射。


从底层数据库的角度来看,实体将如下所示:

customer_id  firstname
-----------  ---------
          1  Ali Baba

customer_id  billingaddress
-----------  --------------
          1  my_address

引用资料:

  • JPA 2.0 规范,第 2.4.1 章:与派生身份对应的主键

关于hibernate - JPA 2.0 - 在父实体上自动持久化子实体持久化,给出 org.hibernate.id.IdentifierGenerationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28859895/

相关文章:

mysql - hibernate ,mysql

java - JPA 2.0 - native 查询中的 NVARCHAR

hibernate - 我怎样才能使带有 IN 的命名查询真正起作用?

JPA persistence.xml META-INF 无法正常工作

java - JBoss 5.1.0.GA 中的 Hibernate 3.5-Final

java - Hibernate继承

hibernate - JPA/Hibernate 提高批量插入性能

java - 事务方法回滚内的 Hibernate 事务方法调用

java - Hibernate : Why FetchType. LAZY-annotated 集合属性急切加载?

hibernate - JPA/Hibernate @ManyToMany 没有在连接表上创建索引