批量插入中的 Postgres 错误:关系“hibernate_sequence”不存在位置 17

Posted

技术标签:

【中文标题】批量插入中的 Postgres 错误:关系“hibernate_sequence”不存在位置 17【英文标题】:Postgres error in batch insert : relation "hibernate_sequence" does not exist position 17 【发布时间】:2015-06-28 14:03:51 【问题描述】:

我正在执行休眠 jpa 批量更新,它给了我以下错误

2015-04-21 15:53:51,907 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (Thread-283 (HornetQ-client-global-threads-462057890)) SQL Error: 0, SQLState: 42P01
2015-04-21 15:53:51,908 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (Thread-283 (HornetQ-client-global-threads-462057890)) ERROR: relation "my_seq_gen" does not exist

我使用的是 postgres 数据库,我的 ID 是自动生成的

  @Id
@SequenceGenerator(name="seq-gen",sequenceName="MY_SEQ_GEN"initialValue=205, allocationSize=12)
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="seq-gen")
@Column(name="\"ID\"",unique=true,nullable=false)
private int id;

这是我的批量插入代码sn-p

getEm().getTransaction().begin();
System.out.println("transaction started--------------");
try    
    for (Receipt ReceiptEntity : arrReceiptEntity) 
            getEm().persist(ReceiptEntity);
    
    getEm().getTransaction().commit();
    System.out.println("commited");
 catch (Exception exception) 
    System.out.println("error----------------------------------------------------------------------");
    if(getEm().getTransaction().isActive())
        getEm().getTransaction().rollback();
    LOG.error(exception);
 finally 
    getEm().flush();
    getEm().clear();
    getEm().close();

我在 persistence.xml 中添加了以下属性

         <property name="hibernate.id.new_generator_mappings" value="true"/>

请指出我做错了什么。

【问题讨论】:

尝试 GenerationType.IDENTITY 而不是 GenerationType.AUTO ***.com/a/25279598/592355 【参考方案1】:

如果您不想更改实体定义,则需要在 postgreSQL 架构中创建一个名为 hibernate_sequence 的序列。

CREATE SEQUENCE hibernate_sequence START 1;

更新

您缺少为实体定义的第二个序列 generatef,只需像上一个一样添加它:

CREATE SEQUENCE my_seq_gen START 1;

什么是序列?

序列是整数的有序列表。序列中数字的顺序很重要。你可以配置最小值和最大值,你应该增加多少:

CREATE SEQUENCE [ IF NOT EXISTS ] sequence_name
  [ AS  SMALLINT | INT | BIGINT  ]
  [ INCREMENT [ BY ] increment ]
  [ MINVALUE minvalue | NO MINVALUE ] 
  [ MAXVALUE maxvalue | NO MAXVALUE ]
  [ START [ WITH ] start ] 
  [ CACHE cache ] 
  [ [ NO ] CYCLE ]

不,您可以在 SQL 命令和休眠中使用 nextval('') 之类的函数从集合中获取下一个值。这比在 sequence_table 中保留当前主键值或在现有表中查找最大 PK 值要便宜得多。因此,它提供了一种简单且廉价的方法来查找给定表的下一个 PK。

所有表通常都使用一个专用的序列,就像在这个例子中一样,它被选为 IdGenerator 策略。

非常有用的教程:

http://www.concretepage.com/hibernate/generatedvalue-strategy-generationtype-sequence-hibernate https://www.postgresql.org/docs/9.5/sql-createsequence.html https://www.postgresqltutorial.com/postgresql-sequences/

【讨论】:

我添加了序列生成器,但它给出了另一个错误,请检查更新的问题 正如你的例外所说,你仍然缺少一个序列 my_seq_gen,像以前一样添加它。 工作,就像一个魅力,不知道当你创建上述序列时实际发生了什么,如果你能提供解释将是最重要的。【参考方案2】:

最近我遇到了同样的问题,我已经通过使用@GenericGenerator 注释解决了它。问题是因为我必须在 liquibase 更改日志中插入数百行带有 SQL 语句的行,并且不知何故 hibernate 在生成 id 之前不会拾取最后一行及其。

@Entity(name = "domain")
@Table(name = "domain", schema = "public")
public class DomainJpa 

    @Getter
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "incrementDomain")
    @GenericGenerator(name = "incrementDomain", strategy = "increment")
    private Integer id;


希望这对某人有用。干杯:)

【讨论】:

【参考方案3】:

检查 application.properties 文件。

确保 spring.jpa.hibernate.ddl-auto = update

【讨论】:

这修复了我最初的错误,与问题中的相同【参考方案4】:

尝试使用@Id@GeneratedValue(strategy = GenerationType.IDENTITY) 注释您的id

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

更新:仅当您的 id 列被声明为 SERIALBIGSERIAL 类型时才有效。

【讨论】:

身份不是 Postgresql 的坏选择吗? ***.com/questions/10041938/… @Erlan 我看不出它为什么不好,无论是从您的链接还是从我的经验。你能解释一下你的观点吗? @VsevolodPoletaev。来自链接的答案提到 IDENTITY 在没有 SEQUENCE 选项时很有用,因为它将禁用批处理执行。但是后来发现在hibernate 5中IDENTITY会将id绑定到SERIAL的序列上,所以应该没问题。感谢您的回答。 @Mikhail,你是对的。它写在文档docs.jboss.org/hibernate/orm/5.2/userguide/html_single/… 中。但这在大多数用例中并不重要。 感谢您的提示和更新! Spring Boot 完成了剩下的工作! ;)【参考方案5】:

将以下内容添加到您的 application.properties

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update 

这将显式设置为在 Spring 启动期间创建或更新所有表。

【讨论】:

【参考方案6】:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

【讨论】:

【参考方案7】:

有时使用@Id @GeneratedValue(strategy=GenerationType.IDENTITY) 注释,您的序列可能会带有空间隔(删除后)和不正确的下一个自动增量位置。尝试设置下一个自动增量值到最大 id 值之后的位置:

ALTER SEQUENCE schema.entity_id_seq RESTART WITH 40072;

【讨论】:

【参考方案8】:

根据帖子 hibernate could not get next sequence value ,将您的 @GeneratedId 列设置为策略 GenerationType.IDENTITY 而不是 GenerationType.SEQUENCE。所以,你会有

@Id
@SequenceGenerator(name="seq-gen",sequenceName="MY_SEQ_GEN"initialValue=205, allocationSize=12)
@GeneratedValue(strategy= GenerationType.IDENTITY, generator="seq-gen")
@Column(name="\"ID\"",unique=true,nullable=false)
private int id;

【讨论】:

【参考方案9】:

在我的情况下,添加属性 name="hibernate.hbm2ddl.auto" value="update",解决了这个问题。您必须在 persistence.xml 中添加提到的属性

【讨论】:

为我工作(但我尝试使用 create)。注意:此选项会删除数据库中的所有数据,仅供开发使用。【参考方案10】:

我遇到了同样的问题。我解决了在 postgres 上的表中自动递增 id 列的问题,就像这样。

ALTER TABLE mytable ALTER COLUMN id SET DEFAULT nextval('mytable_id_seq');

ALTER SEQUENCE mytable_id_seq OWNED BY mytable.id; 

【讨论】:

【参考方案11】:

我希望你能得到答案,但如果你仍在寻找答案,这可能会有所帮助。

我遇到了同样的问题,并用@SequenceGenerator@GeneratedValue 注释了id 的getter 方法。

@SequenceGenerator(name="seq-gen",sequenceName="MY_SEQ_GEN", initialValue=205, allocationSize=12)
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="seq-gen")
public int getId()
    return id;

【讨论】:

没有。它不能解决我的问题。仍然看到Hibernate: select nextval ('hibernate_sequence'),并且这个序列最初在模式中不存在。必须像 CREATE SEQUENCE hibernate_sequence START 1; 一样手动创建它,作为前一个答案。【参考方案12】:

你可以试试以下:

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO, generator = "auto_gen")
  @SequenceGenerator(name = "auto_gen", sequenceName = "A")
  @Column(name = "ID")
  private int id;

谢谢

【讨论】:

我添加了序列生成器,但它给出了另一个错误,请检查更新的问题

以上是关于批量插入中的 Postgres 错误:关系“hibernate_sequence”不存在位置 17的主要内容,如果未能解决你的问题,请参考以下文章

批量从Dataframe插入到DB,忽略Pyspark中的失败行

Postgres 批量插入不同的模式

如何使用 node-postgres 进行批量插入

postgres 使用存储过程批量插入数据

批量插入在 docker 容器中运行的 Postgres 数据库挂起

Spring Boot Hibernate 将数据插入 Postgres 中的错误列