postgresql 在子类的 Hibernate 中为每个表指定不同的序列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4560813/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-20 00:27:50  来源:igfitidea点击:

Specifying distinct sequence per table in Hibernate on subclasses

javahibernatepostgresqlsequence

提问by gutch

Is there a way to specify distinct sequences for each table in Hibernate, if the ID is defined on a mapped superclass?

如果 ID 是在映射的超类上定义的,有没有办法为 Hibernate 中的每个表指定不同的序列?

All entities in our application extend a superclass called DataObjectlike this:

我们应用程序中的所有实体都扩展了一个如下所示的超类DataObject

@MappedSuperclass
public abstract class DataObject implements Serializable {
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "id")
    private int id;
}

@Entity
@Table(name = "entity_a")
public class EntityA extends DataObject { ... }

@Entity
@Table(name = "entity_b")
public class EntityB extends DataObject { ... }

This causes all entities to use a shared sequence, the default hibernate_sequence.

这会导致所有实体使用共享序列,默认hibernate_sequence.

What I would like to do is use a separate sequence for each entity, for example entity_a_sequenceand entity_b_sequencein the example above. If the ID were specified on the subclasses then I could use the @SequenceGeneratorannotation to specify a sequence for each entity, but in this case the ID is on the superclass. Given that ID is in the superclass, is there a way I can use a separate sequence for each entity — and if so, how?

我想做的是为每个实体使用一个单独的序列,例如entity_a_sequenceentity_b_sequence上面的例子。如果在子类上指定了 ID,那么我可以使用@SequenceGenerator注释为每个实体指定一个序列,但在这种情况下,ID 位于超类上。鉴于 ID 在超类中,有没有一种方法可以为每个实体使用单独的序列——如果是这样,如何使用?

(We are using PostgreSQL 8.3, in case that's relevant)

(我们使用的是 PostgreSQL 8.3,以防万一)

回答by Fran?ois Cassin

Have you tried doing it this way ?

你试过这样做吗?

@MappedSuperclass
public abstract class DataObject implements Serializable {
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idgen")
    @Column(name = "id")
    private int id;
}

@Entity
@SequenceGenerator(initialValue = 1, name = "idgen", sequenceName = "entityaseq")
@Table(name = "entity_a")
public class EntityA extends DataObject { 

}

@Entity
@SequenceGenerator(initialValue = 1, name = "idgen", sequenceName = "entitybseq")
@Table(name = "entity_b")
public class EntityB extends DataObject {

}

I'm sorry I don't have the required environment to test it right now but I'll try it later.

很抱歉,我现在没有测试所需的环境,但我稍后会尝试。

回答by Frans

We use this in the abstract superclass of all of our JPA entities:

我们在所有 JPA 实体的抽象超类中使用它:

@Id
@GeneratedValue(generator = "pooled")
@GenericGenerator(name = "pooled", strategy = "org.hibernate.id.enhanced.TableGenerator", parameters = {
        @org.hibernate.annotations.Parameter(name = "value_column_name", value = "sequence_next_hi_value"),
        @org.hibernate.annotations.Parameter(name = "prefer_entity_table_as_segment_value", value = "true"),
        @org.hibernate.annotations.Parameter(name = "optimizer", value = "pooled-lo"),
        @org.hibernate.annotations.Parameter(name = "increment_size", value = "100")})
private Long id;

It's a bit verbose, but it allows setting the prefer_entity_table_as_segment_valuewhich means you don't need to repeat the idfield or the generator annotations in the subclasses.

它有点冗长,但它允许设置prefer_entity_table_as_segment_value这意味着您不需要id在子类中重复字段或生成器注释。

回答by Gumovvy Steven

IHMO there is better way to do this:

IHMO 有更好的方法来做到这一点:

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

It works in my app.

它适用于我的应用程序。

回答by feel good and programming

TABLE generation stretergy uses separate db sequence for each tablebut it is little expensive operation

表生成策略为每个表使用单独的数据库序列,但它的操作代价很小