必须到两个表客户和上传,我在其中跟踪客户上传的项目数量。 它是与共享主键CustomerID
的一对一关系,这是一个唯一的标识符。我正在努力尝试让保存工作。我正在使用Hibernatesuuid2策略来处理唯一标识符的创建/保存。 在我包含上传实体之前,客户将使用 uuid 正确保存。 基本上,我希望每当有人制作客户对象时都会创建上传。
客户:
@Entity
public class Upload implements Serializable {
@Column(name="UPLOADCOUNT", nullable=true, unique=false)
private Integer uploadCount = new Integer(0);
@MapsId ("CUSTOMERID")
@OneToOne (optional=false)
@JoinColumn(name="CUSTOMERID", referencedColumnName = "CUSTOMERID", nullable=false, unique=true )
private Customer customer;
@Id
@Column(name="CUSTOMERID", length=36, nullable=false, unique=true, insertable=false, updatable=false)
private String customerId_;
public Upload(Customer customer) {
this.customer = customer;
}
}
上传:
@Entity
public class Customer implements Serializable {
@Id
@Column(name = "CUSTOMERID", unique = true)
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String customerId;
@OneToOne(mappedBy = "customer", optional = false, cascade = CascadeType.ALL)
private Upload upload ;
public Customer() {
this.upload = new Upload(this);
}
}
要保存的代码:
Customer customer = new Customer();
EntityManager em = EntityManagerUtil.getEntityManager();
EntityTransaction trans = em.getTransaction();
trans.begin();
em.persist(customer);
trans.commit();
例外:
javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): 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 value in column "second_table_uuid" violates not-null constraint
创建对象时,请确保相关实体的构造函数的默认值为 null。如果是包含 B 的实体 A,则只需要 B 的 uuid 中的 null 而不是 A 的 null。但以防万一,您可以将 null 放入所有 UUID,除非您已经知道 fk。
另一个重要的事情是使用 @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