JPA 2.0 - 在父实体上自动持久化子实体持久化,给出 org.hibernate.id.IdentifierGenerationException
JPA 2.0 - Persist child entity automatically on Parent persist, giving org.hibernate.id.IdentifierGenerationException
我有两个实体,名为 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 分配给地址 table,所以我不想手动分配它。谢谢你的时间。
您需要的是所谓的派生标识符。在这种方法中,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 章:对应于派生标识的主键
我有两个实体,名为 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 分配给地址 table,所以我不想手动分配它。谢谢你的时间。
您需要的是所谓的派生标识符。在这种方法中,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 章:对应于派生标识的主键