批量插入中的 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 列被声明为 SERIAL
或 BIGSERIAL
类型时才有效。
【讨论】:
身份不是 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中的失败行