Java MappedSuperclass-更改子类中的SequenceGenerator

Java MappedSuperclass-更改子类中的SequenceGenerator,java,jakarta-ee,jpa,sequence,mappedsuperclass,Java,Jakarta Ee,Jpa,Sequence,Mappedsuperclass,我将JPA2与Hibernate一起使用,并尝试为我的实体引入一个公共基类。目前看来: @MappedSuperclass public abstract class BaseEntity { @Id private Long id; @Override public int hashCode() { // ... } @Override public boolean equals(Object obj) {

我将JPA2与Hibernate一起使用,并尝试为我的实体引入一个公共基类。目前看来:

@MappedSuperclass
public abstract class BaseEntity {

    @Id
    private Long id;

    @Override
    public int hashCode() {
        // ...
    }

    @Override
    public boolean equals(Object obj) {
        // ...
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

但是,对于每个表,都有一个序列
$entityname\u seq
,我想将其用作序列生成器。如何从我的子类设置它?我想我需要重写@GeneratedValue并用@SequenceGenerator创建一个新的SequenceGenerator。

在JPA中,不能用注释来完成。无法重写批注本身。实体从继承所有映射信息。只有两个注释可用于重新定义从映射超类继承的映射:

  • 重写列映射和
  • 覆盖联接列/表

  • 它们都无助于生成价值。

    是的,这是可能的。您可以使用
    @SequenceGenerator
    注释覆盖默认生成器名称

    • 基类
    • 序列(SQL)

    • 派生类

    • 这种方法在Hibernate4.1.x中运行良好,但在EclipseLink 2.x中没有
    编辑

    • 根据评论,它似乎与EclipseLink 2.6.1-RC1一起工作

    使用EclipseLink,您可以使用
    定制程序
    DescriptorUserMizer
    接口定义了一种自定义jpa描述符(也称为持久实体)所有信息的方法

    在映射的超类中:

    @MappedSuperclass
    @Customizer(SequenceCustomizer.class)
    public abstract class AbstractEntity implements Serializable {
        ...
    }
    

    我写这篇文章是因为它太难理解了,因为对公认答案的评论:

    我有一个
    BaseEntity
    ,每个其他实体都继承自:

    BaseEntity.java:

    @MappedSuperclass
    public abstract class BaseEntity {
    
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ID")
        private Long id;
    
    然后我有两个实体
    User
    Order
    ,它们都继承自
    BaseEntity
    ,同时还有
    @SequenceGenerator
    注释:

    User.java:

    @SequenceGenerator(name = "SEQ_ID", sequenceName = "SEQ_USER", allocationSize = 1)
    public class User extends BaseEntity { ... }
    
    Order.java:

    @SequenceGenerator(name = "SEQ_ID", sequenceName = "SEQ_ORDER", allocationSize = 1)
    public class Order extends BaseEntity { ... }
    
    它在H2上至少工作2个序列
    SEQ_USER
    SEQ_ORDERS

    select SEQ_USER.nextval from dual;
    select SEQ_ORDERS.nextval from dual;
    

    我已经用EclipseLink 2.6.1-RC1进行了测试,它也很有效。这是个好消息。非常感谢。我将编辑答案。另外,所有子类都必须定义@SequenceGenerator,否则将为映射抛出错误。这是一个不正确的解决方案。只要您只有一个子类
    persistenentity
    ,它就可以工作。假设您创建的实体“组”还扩展了
    持久实体
    。然后会出现错误,因为序列生成器
    default\u gen
    在同一持久性单元中定义了两次。(EclipseLink 2.6.2)事实上,正如JEE-7所规定的“生成器名称的作用域对于持久化单元是全局的(在所有生成器类型中)。”因此,即使它在某些时间对某些实现起作用,它也不是标准行为。它对多个继承实体起作用,因为Hibernate 5.18.3++默认是容忍的。但在启动过程中会收到警告:
    org.hibernate.boot.internal.InFlightMetadataCollectorImpl-hh000069:重复的生成器名称SEQ_ID
    。另见。如果您对这些警告感到恼火,请查看:
    @MappedSuperclass
    public abstract class BaseEntity {
    
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ID")
        private Long id;
    
    @SequenceGenerator(name = "SEQ_ID", sequenceName = "SEQ_USER", allocationSize = 1)
    public class User extends BaseEntity { ... }
    
    @SequenceGenerator(name = "SEQ_ID", sequenceName = "SEQ_ORDER", allocationSize = 1)
    public class Order extends BaseEntity { ... }
    
    select SEQ_USER.nextval from dual;
    select SEQ_ORDERS.nextval from dual;