【问题标题】:Hibernate not allowing to increment by 5 in sequence休眠不允许按顺序递增 5
【发布时间】:2018-11-26 15:40:34
【问题描述】:

我有以下数据库序列

CREATE SEQUENCE phonebook_id_seq INCREMENT BY 5;

select nextval('phonebook_id_seq'); // 1,6,11,....

Java

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "phoneSequenceGenerator")
@SequenceGenerator(name = "phoneSequenceGenerator", sequenceName = "phonebook_id_seq")
private Long id;

但是,使用 Hibernate,我收到以下错误消息,提示 hibernate 期望增加 50。 为什么会这样?

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: sequence [phonebook_id_seq] defined inconsistent increment-size; found [5] but expecting [50]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:396)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1692)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1630)
    ... 41 common frames omitted
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: sequence [phonebook_id_seq] defined inconsistent increment-size; found [5] but expecting [50]
    at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateSequence(AbstractSchemaValidator.java:191)
    at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:100)
    at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:191)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:313)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:452)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:889)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:384)
    ... 45 common frames omitted

编辑1 添加了java代码。

【问题讨论】:

  • 你能给我们看看你的代码吗!
  • 你正在使用哪些 rdbms
  • 你的意思是,像@SequenceGenerator 的默认分配大小?你在注释/XML 中做了哪些更改,不是吗?
  • @YCF_L 我已经更新了 seq 注释。

标签: java sql hibernate jpa spring-data-jpa


【解决方案1】:

错误信息很清楚。您已启用(或未禁用)模式验证,因此当应用程序启动时,Hibernate 会将数据库与它对注释和/或配置的期望进行比较。 phonebook_id_seq 序列在数据库中定义为增量为 5,但注释显示为 50(或什么也没说,默认值为 50)。更改注释以匹配数据库或更改序列或禁用验证。

我猜测基于标签的spring.jpa.hibernate.ddl-auto=validate 启用了验证,但如果没有看到您的代码,很难确定。

【讨论】:

  • 是这个吗? allocationSize ?
  • 是的,对于带有 phonebook_id_seq 的@SequenceGenerator。
  • 谢谢。 allocationSize 似乎是一些内存、缓冲区分配大小。
【解决方案2】:

通常,您必须匹配数据库中的序列增量大小,以及@SequenceGenerator 中的属性allocationSize

在您的示例中,它将是:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "phoneSequenceGenerator")
@SequenceGenerator(name = "phoneSequenceGenerator", 
                   sequenceName = "phonebook_id_seq", 
                   allocationSize = 5)
private Long id;

Hibernate 将使用org.hibernate.dialect.Dialect#getQuerySequencesString 定义的查询检查数据库中的序列定义。

例如对于 PostgreSQL,它将是

SELECT * FROM information_schema.sequences;

从 Hibernate 5.4 开始,我们还可以配置检测到不匹配时的行为。 默认情况下,它会抛出一个org.hibernate.MappingException

这个新属性:hibernate.id.sequence.increment_size_mismatch_strategy (doc)(由org.hibernate.cfg.AvailableSettings#SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY映射)可以改变这种行为:

hibernate.id.sequence.increment_size_mismatch_strategy(例如 LOG、FIX 或 EXCEPTION(默认值))

此设置定义了当 Hibernate 检测到实体映射中的序列配置与其数据库序列对象对应项之间不匹配时使用的 org.hibernate.id.SequenceMismatchStrategy。

默认值由 org.hibernate.id.SequenceMismatchStrategy#EXCEPTION 给出,表示检测到此类冲突时会抛出异常。

因此,如果您将其设置为“FIX”,Hibernate 将自动将 allocationSize 配置为 5。 还会记录一个警告,如下所示:

WARN ...enhanced.SequenceStyleGenerator (SequenceStyleGenerator.java:270) - HHH000497:[SEQ_NAME] 序列的增量大小在实体映射中设置为 [5],而关联的数据库序列增量大小为 [5] .数据库序列增量大小将优先避免标识符分配冲突。

是的,在 'FIX' 值的情况下,日志消息似乎是错误的,它应该为第一个值打印 50...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多