我有一个带有复合键的休眠实体,其中键由长 ID 和时间戳组成。ID 应使用序列生成器。
我的实体:
@Entity
@Table(name="MY_ENTITY")
public class MyEntity {
private MyEntityPk myEntityPk;
@EmbededId
public MyEntityPk getMyEntityPk() {
return myEntityPk;
}
// setter omitted
// other properties/getters/setters omitted
}
我的实体库:
public class MyEntityPk implements Serializable {
// version UID/hashCode()/equals() omitted
private Long myEntityId;
private Timestamp revisionTime;
@Column(name = "MY_ENTITY_ID", unique = true, nullable = false, precision = 13, scale = 0)
@GeneratedValue(strategy=GenerationType.AUTO, generator="HIBERNATE_SEQUENCE_GEN")
@SequenceGenerator(name="HIBERNATE_SEQUENCE_GEN", sequenceName="HIBERNATE_SEQUENCE")
public Long getMyEntityId() {
return myEntityId;
}
public void setMyEntityId(Long myEntityId) {
this.myEntityId = myEntityId;
}
@Column(name = "REVISION_TS", nullable = false)
public Timestamp getRevisionTime() {
return revisionTime;
}
public void setRevisionTime(Timestamp revisionTime) {
this.revisionTime = revisionTime;
}
}
PK 看起来连接正确。当我全部查找时,我有一个 MyEntity 对象列表,其中每个 MyEntityPk 对象都有一个来自数据库的 id 和 revisionTime。
但是,在插入时,以下内容给了我一个错误,表明 MY_ENTITY_ID 为空,并且数据库不允许该列的空值。对于我们的其他实体,我们可以插入自动生成的 ID 并将其保留为空,Hibernate 知道从数据库中获取下一个序列并在实体中使用它。在这种情况下,由于某种原因没有发生:
MyEntity e = new MyEntity();
MyEntityPk pk = new MyEntityPk();
pk.setRevisionTime(new Timestamp(System.currentTimeMillis()));
//pk.setMyEntityId(5l); // see note below
e.setMyEntityPk(pk);
// setting a bunch of other entity parameters omitted
Session session = getSession();
session.saveOrUpdate( entity );
最终给了我:
// a bunch of stack trace omitted
Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("MY_SCHEMA"."MY_ENTITY"."MY_ENTITY_ID")
// more stack trace omitted
请注意,如果我手动设置 PK 对象的 ID,插入将起作用。