提问人:Tim Lammarsch 提问时间:8/6/2022 最后编辑:MWiesnerTim Lammarsch 更新时间:8/7/2022 访问量:436
在 JPA 中以 @GeneratedValue 作为 Sequence 生成主键,但使用外部数据库访问使其工作
Generate primary key with @GeneratedValue in JPA as Sequence, but make it work using external Database Access
问:
我正在使用 PostgreSQL 12.11、JPA 3.1.0 和 Hibernate 5.6.10。我不想过分说明问题,但某些方面可能取决于实现。
我想生成一个以自动生成的 id 值作为主键的表,该表应该从 JPA 自动生成,但它也应该可以通过外部工具访问。BIGINT
如果我在 JPA 中使用 @GeneratedValue(即使使用 GenerationType.SEQUENCE), 不会设置数据库的默认值列注,因此 PostgreSQL 特定的 ID 生成不会不起作用。
如果我在 JPA 中使用 @GeneratedValue 和 columnDefinition = “BIGSERIAL”,则始终会有两个序列,即使指定 适当的名称,我很确定这将创建 相互冲突的价值观。(不过,我还没有测试过。
如果我根本不使用 @GeneratedValue,但 columnDefinition = “BIGSERIAL”,我将能够使用其他工具插入,但不能使用 JPA,其中 id 将始终为 0。
如果我使用 @GeneratedValue 并使用 columnDefinition 手动将默认值设置为序列的 nextval 调用,它将 生成时失败,因为当时序列不存在。
我现在正在做的是使用变体 1。对于外部访问,我手动将 id 设置为 nextval 的结果。这并不完美。对于 COPY,我什至需要一个 TEMPORARY TABLE。有没有一些“最佳方法”应该这样做?
答:
多亏了@MWiesner,我可以解决这个问题(比较上面的评论):
看起来,我的问题是 10+ 版之前与 PostgreSQL 更大的兼容性问题的一部分。从那时起,可以(并推荐)使用 GenerationType.IDENTITY。
通过研究这一点,我还了解到 PostgreSQL 10+ IDENTITY 在后台用作序列 - 这很重要,因为许多较旧的网站因为性能问题而不鼓励 IDENTITY。AFAICS 对于这个较新的实现来说,情况并非如此。
所以我现在正在做的是使用 GenerationType.IDENTITY,一切正常。
更多琐事:
- 对于上面提到的版本,GenerationType.AUTO 默认为 SEQUENCE,而不是 IDENTITY。
- JPA 将 PostgreSQL 配置设置为“默认生成为标识”,而不是“始终作为标识生成”。根据具体情况,这可能较差。我还没有找到如何改变它。
评论