2013-01-08 55 views
0

我有一个带有组合键的Hibernate实体,其中键由长ID和时间戳组成。该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为空,并且数据库不会允许该列的空值。通过我们的其他实体,我们可以插入并保留自动生成的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,插件会工作。

回答

1

我只使用过的复合密钥,其对其他表的引用,但看看那一个JPA Composite Key + Sequence

起初似乎是个坏消息,但如果你读了接受的答案的评论你可能会得到幸运

+0

你说得对,这是个坏消息。我遗漏了我们使用的是旧版本的Hibernate(3.3),并且它似乎已经在3.5中修复了。我可以通过在保存之前手动从序列中获取ID来解决此问题。 –