问题

是否可以对某些列使用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@GeneratedValueannotation仅与@Id一起使用以创建自动编号。

@GeneratedValueannotation只是告诉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)

原文链接