问题
是否可以对某些列使用DB序列,而不是标识符/不是复合标识符的一部分?
我正在使用hibernate作为jpa提供程序,并且我有一个表有一些生成值的列(使用序列),尽管它们不是标识符的一部分。
我想要的是使用序列为实体创建一个新值,其中序列的列是NOT(部分)主键:
@Entity
@Table(name = "MyTable")
public class MyEntity {
//...
@Id //... etc
public Long getId() {
return id;
}
//note NO @Id here! but this doesn't work...
@GeneratedValue(strategy = GenerationType.AUTO, generator = "myGen")
@SequenceGenerator(name = "myGen", sequenceName = "MY_SEQUENCE")
@Column(name = "SEQ_VAL", unique = false, nullable = false, insertable = true, updatable = true)
public Long getMySequencedValue(){
return myVal;
}
}
然后,当我这样做:
em.persist(new MyEntity());
将生成id,但是我的JPA提供程序也将生成mySequenceVal
属性。
只是为了说清楚:我想要Hibernate来生成mySequencedValue
属性的值。我知道Hibernate可以处理数据库生成的值,但我不想使用触发器或除Hibernate本身之外的任何其他东西来生成我的属性的值。如果Hibernate可以为主键生成值,为什么不能为简单属性生成?
#1 热门回答(54 赞)
寻找这个问题的答案,我偶然发现了this link
似乎Hibernate / JPA无法为你的非id属性自动创建值。 The@GeneratedValue
annotation仅与@Id
一起使用以创建自动编号。
@GeneratedValue
annotation只是告诉Hibernate数据库本身正在生成这个值。
该论坛中建议的解决方案(或解决方法)是使用生成的Id创建一个单独的实体,如下所示:
@Entity
public class GeneralSequenceNumber {
@Id
@GeneratedValue(...)
private Long number;
}
@Entity
public class MyEntity {
@Id ..
private Long id;
@OneToOne(...)
private GeneralSequnceNumber myVal;
}
#2 热门回答(29 赞)
我发现@Column(columnDefinition="serial")
完美但只适用于PostgreSQL。对我来说这是完美的解决方案,因为第二个实体是"丑陋"的选择。
#3 热门回答(14 赞)
我知道这是一个非常古老的问题,但它首先显示了结果,jpa自问题以来发生了很大的变化。
现在正确的方法是使用@Generated
注释。你可以定义序列,将列中的默认值设置为该序列,然后将列映射为:
@Generated(GenerationTime.INSERT)
@Column(name = "column_name", insertable = false)