【问题标题】:How to use Postgres sequence with JPA?如何在 JPA 中使用 Postgres 序列?
【发布时间】:2015-06-08 20:33:37
【问题描述】:

我的 postgresql 数据库中有一个“客户”表,其中包含一个特定字段:cus_number,其中定义了一个序列。该字段不是主键,已有cus_id字段。

cus_number 的默认值为

nextval('customer_cus_number_seq'::regclass) it's the sequence.

使用 pgadmin 时,当我在此客户表中插入一行,其值为 cus_number 时,它可以正常工作并使用默认值序列。 但是在我的 webap 中,当我坚持一个 new Customer() 时,插入的行在字段 cus_number 中没有任何内容。

这是我的自定义实体定义:

public class Customer implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "pers_id")
private Integer id;

...

@Column(name = "cus_number")
private Integer number;

...

}

还有序列脚本:

  CREATE SEQUENCE customer_cus_number_seq
  INCREMENT 1
  MINVALUE 100
  MAXVALUE 9223372036854775807
  START 114
  CACHE 1;

ALTER TABLE customer_cus_number_seq fizzconsulting 的所有者;

请给我一些建议吗?

谢谢。

【问题讨论】:

  • "当我在这个客户表中插入一行时,它的 cus_number 为空值" - 不,它没有。如果您提供 NULL 值,则将存储 NULL 值。默认子句仅在insert 语句的列列表中未提及该列时使用(这与提供NULL 值不同)
  • 是的,你是对的!这解释了为什么在没有 cus_number 的情况下进行插入时会设置默认值(序列)。但是使用 JPA,我如何避免在持久化客户实体时设置空值?
  • 您创建了一个序列。 GenerationType.IDENTITY 用于不同的目的(用于自动增量列)。您需要在字段private Integer id; @SequenceGenerator(name = "customerIdSequence", sequenceName = "customer_cus_number_seq", allocationSize=1, initialValue=1) 上方的行中添加@SequenceGenerator,然后使用@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "customerIdSequence") 引用此序列。免责声明:我不使用 PostgreSQL,但它在概念上应该与我过去使用的 Oracle 相同。
  • @a_horse_with_no_name 或提供了明确的DEFAULT 关键字,但似乎很少有应用程序和工具支持:-(

标签: postgresql jpa


【解决方案1】:

@Tiny,下一个是正确的定义吗?

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@SequenceGenerator(name = "customerNumberSequence", sequenceName = "customer_cus_number_seq", allocationSize = 1, initialValue = 100)
@Basic(optional = false)
@Column(name = "pers_id")                                                                       
private Integer id;
...
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "customerNumberSequence")
@Column(name = "cus_number")
private Integer number;
...

JPA 似乎不接受此声明: 异常描述:类 [class tfe.entity.Customer] 有两个 @GeneratedValues:用于字段 [customer.cus_number] 和 [customer.pers_id]。只允许一个。

谢谢。

【讨论】:

  • 你为什么还有 IDENTITY 呢?你说你使用的是序列,所以使用 SEQUENCE。为什么现在将 SEQUENCE 放在“数字”字段上?它应该继续“id”
【解决方案2】:

好的,解决方法如下:

为了允许该字段的数据库默认值(即序列 cus_number_seq 的 nextval),JPA 在持久化事务时必须不引用 cus_number 值。为此,只需注释 @Column(name = "cus_number", insertable = false) 这样在插入新客户时不会提及该字段,因此默认值nextval序列使用DB端。

它现在工作正常。 感谢您的提示。

【讨论】:

  • 使用这种方法插入可以工作,但是插入查询不会返回序列生成的值。有什么建议吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 1970-01-01
  • 2022-08-19
  • 2017-02-11
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多