34

我将 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_seq我想用作序列生成器的序列。如何从我的子类中设置它?我想我需要覆盖@GeneratedValue 并使用@SequenceGenerator 创建一个新的SequenceGenerator。

4

4 回答 4

39

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

  • 基类
    @MappedSuperclass
    public abstract class PersistentEntity implements Serializable
    {
        private static final long serialVersionUID = 1L;

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "default_gen")
        protected Long id = 0L;

        public Long getId()
        {
            return id;
        }

        public void setId(Long id)
        { 
            this.id = id;
        }
    }
  • 序列 (SQL)

    create sequence role_seq;
  • 派生类

    @Entity
    @Table(name = "role")
    @SequenceGenerator(name = "default_gen", sequenceName = "role_seq", allocationSize = 1)
    public class Role extends PersistentEntity implements Serializable
    {
        private static final long serialVersionUID = 1L;

        @NotNull
        @Size(max = 32)
        private String name;

        public String getName()
        {
             return name;
        }

        public void setName(String name)
        {
             this.name = name;
        }   
    }
  • 这种方法在 Hibernate 4.1.x 中运行良好,但在 EclipseLink 2.x 中却不行。

编辑

  • 根据评论,它似乎正在使用 EclipseLink 2.6.1-RC1。
于 2012-08-28T02:22:32.843 回答
12

在 JPA 中,注释无法完成。注释本身不能被覆盖。Entity 继承了MappedSuperClass的所有映射信息。只有两个注解可用于重新定义从映射超类继承的映射:

  1. AttributeOverride覆盖列映射和
  2. AssociationOverride覆盖连接列/表。

他们都没有帮助 GeneratedValue。

于 2012-07-17T19:00:57.053 回答
4

借助 EclipseLink,您可以使用Customizer. DescriptorCustomizer接口定义了一种自定义有关 jpa 描述符(又名持久实体)的所有信息的方法。

public class SequenceCustomizer implements DescriptorCustomizer {

    @Override
    public void customize(ClassDescriptor descriptor) throws Exception {
        descriptor.setSequenceNumberName(descriptor.getTableName());
    }
}

并在您映射的超类中:

@MappedSuperclass
@Customizer(SequenceCustomizer.class)
public abstract class AbstractEntity implements Serializable {
    ...
}
于 2015-09-11T17:36:00.727 回答
3

我正在写这个,因为它变得太难以理解,因为对已接受答案的评论:

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

BaseEntity.java:

@MappedSuperclass
public abstract class BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ID")
    private Long id;

然后我有两个实体UserOrder它们都继承自BaseEntity,同时也有@SequenceGenerator注释:

用户.java:

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

订单.java:

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

它至少在 H2 上使用 2 个序列SEQ_USERSEQ_ORDERS

select SEQ_USER.nextval from dual;
select SEQ_ORDERS.nextval from dual;
于 2019-10-24T14:17:37.953 回答