Hibernate架构参数在@SequenceGenerator注释中不起作用

时间:2010-04-09 09:37:43

标签: hibernate postgresql schema sequence jpa-2.0

我有以下代码:

@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注释3.5.0-最终。

保存MyClass的对象时,它会生成以下SQL查询:

select nextval('my_table_id_seq')

因此没有模式前缀,因此无法找到序列。当我像

一样编写sequenceName时
sequenceName = "my_schema.my_table_id_seq"
一切正常。

我对架构参数的含义有误解吗?还是错误?任何想法如何使架构参数工作?

11 个答案:

答案 0 :(得分:7)

这里的问题相同,对我来说看起来像个错误。我正在使用hibernate 3.6.7 查看源代码,我看到方法org.hibernate.cfg.annotations.reflection.JPAOverridenAnnotationReader#buildSequenceGeneratorAnnotation(Element element)似乎复制了namesequence-nameinitial-valueallocation-size属性的值,但我看不到引用catalogschema

我希望看到类似于方法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);

所以,即使有点hackish,至少这个版本的方式似乎也正如你所说的那样为sequenceName添加前缀。

答案 1 :(得分:5)

我的解决方法看起来像这样(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)

答案 2 :(得分:1)

这听起来像个错误:JPA提供商应该遵守schema注释的“新”(自Java Persistence 2.0)catalog@SequenceGenerator属性。我建议提出a Jira issue(注释和实体经理项目现在是核心),找不到任何现有项目。

答案 3 :(得分:1)

同样的问题,在Oracle Database 11g企业版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注释的模式属性中使用的

答案 4 :(得分:1)

我在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;

请参见sequenceName之前的“ sisbp”。 sequenceName是“ seq_area_tematica”,现在是“ sisbp”(模式)+“ seq_area_tematica”。

答案 5 :(得分:0)

嗯,我不太喜欢hibernate的内部,但这里有一些信息:

https://forum.hibernate.org/viewtopic.php?p=2406761

您还可以通过ALTER USER ... SET SEARCH_PATH

为连接到PostgreSQL的用户设置默认架构

答案 6 :(得分:0)

尝试将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;

答案 7 :(得分:0)

在此处使用休眠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()方法。提供给该方法的唯一信息是在sequenceName上定义的@SequenceGenerator属性:

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;
    }
}

我没有使用最后一种方法来更改序列的名称,因为它似乎不太适合我的情况。

答案 8 :(得分:0)

就我而言,执行不会通过@jambriz指示的位置进行。

版本:休眠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类中。在if块的第455行中,您可以看到正在设置的方案。否则,未设置方案。

希望这会有所帮助!

答案 9 :(得分:0)

在Spring中使用休眠模式时 请设置

<prop key="hibernate.id.new_generator_mappings">true</prop>

答案 10 :(得分:-5)

您好我遇到了同样的问题

但将hibernate.hbm2ddl.auto设置为更新并运行。

<property name="hibernate.hbm2ddl.auto">update</property>