添加具有相同键的@OneToOne关系的父项和子项时,我不断收到此错误。建议使用@MapsId。
id.标识符生成异常:尝试从空的一对一属性分配 id
我尝试了通常的解决方案,但这并没有解决问题。
- 让父项和子项相互指向
- 正确的事务性(是 springframework 的(
- 使用所有者的存储库进行保存。由于违反了上限限制,这不起作用。
我的父实体是(名称有目的(:
@Entity
@Table(name = "JOHAN_SHARED_SUPPLIER")
public class EntitySharedSupplier {
@Id
@Column(name = "supplier_shared_id")
private Long javaSharedSupplierId;
@Column(name = "supplier_shared_name")
private String javaSharedSupplierName;
@Column(name = "contact_shared_name")
private String javaSharedSupplierContactName;
@OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY,
mappedBy = "supplierSharedRef", orphanRemoval = true)
private EntitySharedProduct javaSharedProduct;
孩子是:
@Entity
@Table(name = "JOHAN_SHARED_PRODUCTS")
public class EntitySharedProduct {
@Id
@Column(name = "shared_supplier_id")
private Long javaSupplierSharedId;
@MapsId
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="shared_supplier_id")
private EntitySharedSupplier supplierSharedRef;
@Column(name = "prod_supplier_name")
private String javaSharedProductName;
父级的存储库是:
@Repository
@Transactional
public interface SupplierSharedRepo extends JpaRepository<EntitySharedSupplier, Long> {
}
服务代码:
@Transactional
public void saveSupplier(int sup) {
EntitySharedSupplier supplier = new EntitySharedSupplier();
supplier.setJavaSharedSupplierId((long) sup);
supplier.setJavaSharedSupplierName("SharedSupplier-" + sup);
supplier.setJavaSharedSupplierContactName("SharedSupplier-contact-" + sup);
EntitySharedProduct product = new EntitySharedProduct();
product.setJavaSharedProductName("SharedSupplier-Book-" + sup);
product.setSupplierSharedRef(supplier);
supplier.setJavaSharedProduct( product);
supplierSharedRepo.save(supplier);
}
在这种情况下,解决方案有点困难。
解决方案是通过更改父对象中的设置 id/key 方法:
public void setJavaSharedSupplierId(Long javaSupplierId) {
this.javaSharedSupplierId = javaSupplierId;
if( javaSharedProduct != null) {
javaSharedProduct.setJavaSupplierSharedId( javaSupplierId);
}
}
注意:
- 在大多数情况下,在休眠/jpa 保存过程的后期,您会自动生成父级的 ID/密钥。那时,父母和孩子之间的联系已经完成。
- 在这种情况下,解决方案有效,因为首先在父级和子级之间建立连接,然后设置父级的手动 ID/密钥。
在那之前,我一直得到原始错误(如问题所示(或未设置 id 的 id。
该解决方案需要在创建父/子对象时进行少量更改。
@Transactional
public void saveSupplier(int sup) {
EntitySharedSupplier supplier = new EntitySharedSupplier();
supplier.setJavaSharedSupplierName("SharedSupplier-" + sup);
supplier.setJavaSharedSupplierContactName("SharedSupplier-contact-" + sup);
EntitySharedProduct product = new EntitySharedProduct();
product.setJavaSharedProductName("SharedSupplier-Book-" + sup);
product.setSupplierSharedRef(supplier);
supplier.setJavaSharedProduct( product);
// The next statement has to be put after the previous
supplier.setJavaSharedSupplierId((long) sup);
supplierSharedRepo.save(supplier);
}
该解决方案有效且易于理解。我也有软件不需要在父 ID 中手动设置子 ID。到目前为止,我还没有找到该软件为什么有效。
如果您有更好的解决方案,请告诉我/我们!