Hibernate jpa2.0+;一对一+;未设置共享主键
必须有两个表Customer和Upload,其中我跟踪客户上传的项目数量。它是与共享主键Hibernate jpa2.0+;一对一+;未设置共享主键,hibernate,jpa-2.0,one-to-one,hibernate-4.x,Hibernate,Jpa 2.0,One To One,Hibernate 4.x,必须有两个表Customer和Upload,其中我跟踪客户上传的项目数量。它是与共享主键CustomerID的一对一关系,该主键是唯一标识符。我正在努力使这一保存生效。我使用Hibernates uuid2策略来处理唯一标识符的创建/保存。在我包含上传实体之前,客户将使用uuid正确保存。基本上,我希望在任何时候有人创建客户对象时创建上传 客户: @实体 公共类上载实现可序列化{ @列(name=“UPLOADCOUNT”,nullable=true,unique=false) 私有整数uplo
CustomerID
的一对一关系,该主键是唯一标识符。我正在努力使这一保存生效。我使用Hibernates uuid2策略来处理唯一标识符的创建/保存。在我包含上传实体之前,客户将使用uuid正确保存。基本上,我希望在任何时候有人创建客户对象时创建上传
客户:
@实体
公共类上载实现可序列化{
@列(name=“UPLOADCOUNT”,nullable=true,unique=false)
私有整数uploadCount=新整数(0);
@MapsId(“客户ID”)
@OneToOne(可选=错误)
@JoinColumn(name=“CUSTOMERID”,referencedColumnName=“CUSTOMERID”,nullable=false,unique=true)
私人客户;
@身份证
@列(name=“CUSTOMERID”,长度=36,可空=false,唯一=true,可插入=false,可更新=false)
私有字符串customerId;
公开上载(客户){
this.customer=customer;
}
}
上传:
@实体
公共类Customer实现了可序列化{
@身份证
@列(name=“CUSTOMERID”,unique=true)
@GeneratedValue(generator=“uuid”)
@GenericGenerator(name=“uuid”,strategy=“uuid2”)
私有字符串customerId;
@OneTONE(mappedBy=“customer”,可选=false,级联=CascadeType.ALL)
私人上传;
公众客户(){
this.upload=新上传(this);
}
}
要保存的代码:
Customer=新客户();
EntityManager em=EntityManagerUtil.getEntityManager();
EntityTransaction trans=em.getTransaction();
trans.begin();
em.persist(客户);
trans.commit();
例外情况:
javax.persistence.PersistenceException:org.hibernate.id.IdentifierGenerationException:调用save()之前必须手动分配此类的id:Upload
代替@JoinColumn
您可以尝试以下方法:
@PrimaryKeyJoinColumn(name="CUSTOMERID", referencedColumnName="CUSTOMERID")
更多细节
或者另一个可能的解决方案:像这样更新您的Upload
类
@Id
@Column(name="CUSTOMERID", length=36, nullable=false, unique=true, insertable=false, updatable=false)
@GeneratedValue(generator=”foreign”)
@GenericGenerator(name=”foreign”, strategy = “foreign”, parameters = {@Parameter(name=”property”, value=”customer”)})
private String customerId_;
创建自生成的UUID相关实体的重要事项是将UUID设置为null值。
如果我们硬编码uuid,例如,uuid.randomUUID(),我们将得到一个类似于PSQLException:null列“second_table_uuid”中的null值违反not null约束的fk错误
创建对象时,请确保相关实体的构造函数的默认值为null。如果是包含B的实体A,则只需要在B的uuid中设置null,而不需要在A的uuid中设置null。但如果您不知道fk,则可以将null设置为所有uuid
另一件重要的事情是使用@JoinColumn
而不是@PrimaryKeyJoinColumn
,这也会产生错误
我附加了一段我自己编写的代码
@Entity
@Table(name = "parent")
data class Parent(
@Id
@GeneratedValue
@Column(name = "parent_uuid")
val parentUUID: UUID? = null,
@OneToOne(cascade = [CascadeType.ALL])
@JoinColumn(name = "child_uuid", referencedColumnName = "child_uuid")
var child: Child
) {
constructor() : this(child = Child())
}
@Entity
@Table(name = "child")
data class Child(
@Id
@GeneratedValue
@Column(name = "child_uuid")
val childUUID: UUID? = null,
@Column(name = "name")
val name: String,
) {
constructor() : this(name = "")
}
在UUID中,组合将保留隐式空值
val child = Child(name = "test")
val parent = Parent(child = child)
GL感谢您的快速响应,但我仍然得到了相同的错误。@Nadin刚刚用另一种可能的解决方案(使用hibernate特定的东西)编辑了我的文章,得到了相同的结果。我认为这是一种常见的情况。在您的“保存”代码中:什么是
实体
?它是客户。我已经更新了代码