0

我有一个带有复合键的休眠实体,其中键由长 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,插入将起作用。

4

1 回答 1

1

我只使用过引用其他表的复合键,但看看那个JPA 复合键 + 序列

起初似乎是个坏消息,但如果您阅读已接受答案的评论,您可能会很幸运

于 2013-01-08T16:44:48.460 回答