Hibernate 模式参数在 @SequenceGenerator 注释中不起作用
Posted
技术标签:
【中文标题】Hibernate 模式参数在 @SequenceGenerator 注释中不起作用【英文标题】:Hibernate schema parameter doesn't work in @SequenceGenerator annotation 【发布时间】:2011-02-06 01:45:37 【问题描述】:我有以下代码:
@Entity
@Table(name = "my_table", schema = "my_schema")
@SequenceGenerator(name = "my_table_id_seq", sequenceName = "my_table_id_seq",
schema = "my_schema")
public class MyClass
@Id
@GeneratedValue(generator = "my_table_id_seq",
strategy = GenerationType.SEQUENCE)
private int id;
数据库:Postgresql 8.4,Hibernate annotations 3.5.0-Final。
保存 MyClass 的对象时,它会生成以下 SQL 查询:
select nextval('my_table_id_seq')
因此没有架构前缀,因此无法找到序列。当我写像
这样的 sequenceNamesequenceName = "my_schema.my_table_id_seq"
一切正常。
我对架构参数的含义有误解还是错误?任何想法如何使架构参数工作?
【问题讨论】:
我在这里遇到了同样的问题,并将架构放在序列名称上,就像你做的那样。我的 @SequenceGenerator 没有架构属性。 【参考方案1】:这里有同样的问题,对我来说似乎是一个错误。我正在使用休眠 3.6.7
查看源代码,我看到了一个方法org.hibernate.cfg.annotations.reflection.JPAOverridenAnnotationReader#buildSequenceGeneratorAnnotation(Element element)
,它似乎复制了name
、sequence-name
、initial-value
和allocation-size
attributes 的值,但我看不到对catalog
或schema
的引用
我希望看到类似于方法getTable(Element tree, XMLContext.Default defaults)
(属于同一类)的东西,它具有
annotation.setValue("schema", table.schema());
annotation.setValue("catalog", table.catalog());`
或buildTableGeneratorAnnotation
有
copyStringAttribute(ad, element, "catalog", false);
copyStringAttribute(ad, element, "schema", false);
所以,即使有点老套,至少对于这个版本来说,就像你说的那样,似乎是在 sequenceName
前面加上前缀。
【讨论】:
【参考方案2】:我的解决方法如下所示(JPA 2.1、Hibernate 4.3.8.Final、PostgreSQL 9.4):
@SequenceGenerator(name = "seq_name", sequenceName = "my_schema.seq_name", schema = "my_schema", allocationSize = 1, initialValue = 1)
【讨论】:
【参考方案3】:我在 postgresql 9.6 中通过仅在序列名称前添加我的架构解决了这个问题,如下所示:
(before) sequence name: seq_area_tematica
(after) sequence name: sisbp.seq_area_tematica
及其作品。见代码:
@Id
@Column(name="seq_area_tematica")
@GeneratedValue(generator="sequence",strategy=GenerationType.SEQUENCE)
@SequenceGenerator(name="sequence",sequenceName="sisbp.seq_area_tematica")
private Long id;
参见序列名称前的“sisbp”。 sequenceName 是“seq_area_tematica”,现在是“sisbp”(模式)+“seq_area_tematica”。
【讨论】:
【参考方案4】:在这里使用 Hibernate 4.2.0.Final
并有同样的问题。看起来这是另一个用户回答的错误。我想为序列使用动态模式,具体取决于为会话设置的模式,但对于某些序列,我想使用public
模式。所以对我来说,我不得不使用你提出的解决方案:将模式名称放在我想使用特定模式的序列名称上:
@SequenceGenerator(name = "my_table_id_seq", sequenceName="my_schema.my_table_id_seq",
schema = "my_schema")
对于我想为会话使用架构集的情况,我使用了sequenceName
,而没有预先设置架构。
对于那些希望所有序列都使用相同架构的人,您可以使用hibernate.default_schema
属性。这样您就无需更改 @SequenceGenerator
属性:
<prop key="hibernate.default_schema">my_schema_name</prop>
我正在使用 PostgreSQL DBMS。如果您想在 Hibernate 调用 nextval('my_sequence')
时动态更改序列的名称,您可以扩展您的数据库方言类并配置 Hibernate 以使用。您只需要覆盖 getSequenceNextValString()
方法。提供给该方法的唯一信息是在@SequenceGenerator
上定义的sequenceName
属性:
public class SchemaPostgreSQLDialect extends PostgreSQL82Dialect
@Override
public String getSequenceNextValString(String sequenceName)
String seqFinalName = mySequenceNameModifierMethod(sequenceName);
return "select nextval('" + seqFinalName + "')";
private String mySequenceNameModifierMethod(String originalSequenceName)
// magic modification here
return modifiedSequenceName;
我没有使用最后一种方式来更改序列的名称,因为它似乎不太适合我的情况。
【讨论】:
【参考方案5】:这听起来像是一个错误:JPA 提供程序应该尊重 @SequenceGenerator
注释的“新”(自 Java Persistence 2.0 起)schema
和 catalog
属性。我建议提出a Jira issue(注解和实体管理器项目现在都在核心下),找不到任何现有的。
【讨论】:
【参考方案6】:同样的问题,在 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 上使用 Hibernate 4.3.6.Final 和 Spring 4.1.4.RELEASE。
看起来这是一个错误 => https://hibernate.atlassian.net/browse/HHH-7232
我们通过在模式 A 中创建一个指向模式 B 中的序列的同义词来解决这个问题。这个同义词是我们在 @SequenceGenerator 注释的模式属性中使用的
【讨论】:
据称已在 5.x 版本中修复:hibernate.atlassian.net/browse/…【参考方案7】:嗯,我不太喜欢使用 hibernate 的内部结构,但这里有一些信息:
https://forum.hibernate.org/viewtopic.php?p=2406761
您还可以为通过 ALTER USER ... SET SEARCH_PATH 连接到 PostgreSQL 的用户设置默认架构
【讨论】:
【参考方案8】:尝试将SequenceGenerator 注释从POJO 的类声明移至id 字段声明。使用 Hibernate 3.6.4 这个
@Entity
@Table(name = "my_table", schema = "my_schema")
public class MyClass
@Id
@GeneratedValue(generator = "my_table_id_seq",
strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "my_table_id_seq", sequenceName = "my_table_id_seq", schema = "my_schema")
private int id;
为 mysql 生成这个
create table my_schema.my_table_id_seq (
next_val bigint
);
insert into my_schema.my_table_id_seq values ( 1 );
这适用于 PostgreSQL
create sequence my_schema.my_table_id_seq start 1 increment 50;
【讨论】:
【参考方案9】:在我的情况下,执行不会通过@jambriz 指示的位置。
版本:Hibernate 3.6.10.Final
当hibernate.id.new_generator_mappings = false
在persistence.xml
时出现问题。当设置为true
或简单地删除时,Hibernate 使用序列方案来构建 SQL。 解决方案:
<property name="hibernate.id.new_generator_mappings" value="true" />
<!-- Or remove this property -->
代码哪里出了问题?
在第 445 行和第 480 行之间的 AnnotationBinder.java 类中。在第 455 行的 if
块中,您可以看到正在设置的方案。在 else 中没有设置方案。
希望这会有所帮助!
【讨论】:
【参考方案10】:当使用带有弹簧的休眠时 请设置
<prop key="hibernate.id.new_generator_mappings">true</prop>
【讨论】:
【参考方案11】:你好,我遇到了同样的问题
但将您的 hibernate.hbm2ddl.auto 设置为更新并运行。
<property name="hibernate.hbm2ddl.auto">update</property>
【讨论】:
我知道这是事后诸葛亮,但这个答案是不正确的,因为它只会在默认模式中创建生成器,这可能不是你想要的。以上是关于Hibernate 模式参数在 @SequenceGenerator 注释中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
模式验证:缺少表 [hibernate_sequences]
在 Hibernate 中使用 SEQUENCE 时导致唯一约束违规的原因是啥?