キーがロングIDとタイムスタンプで構成されている複合キーを持つHibernateエンティティがあります。IDはシーケンスジェネレーターを使用する必要があります。
MyEntity:
@Entity
@Table(name="MY_ENTITY")
public class MyEntity {
private MyEntityPk myEntityPk;
@EmbededId
public MyEntityPk getMyEntityPk() {
return myEntityPk;
}
// setter omitted
// other properties/getters/setters omitted
}
MyEntityPk:
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がnullであり、dbがその列にnull値を許可しないことを示すエラーが発生します。他のエンティティでは、自動生成されたIDを挿入してnullのままにすることができ、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を手動で設定すると、挿入が機能することに注意してください。