MappedSuperclass - Change SequenceGenerator in Subclass

后端 未结 4 1885
暖寄归人
暖寄归人 2020-11-29 07:07

I\'m using JPA2 with Hibernate and try to introduce a common base class for my entities. So far it looks like that:

@MappedSuperclass
public abstract class B         


        
相关标签:
4条回答
  • 2020-11-29 07:44

    Yes, it is possible. You can override the default generator name with the @SequenceGenerator annotation.

    • Base class
        @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;
            }
        }
    • Sequence (SQL)

      create sequence role_seq;
    • Derived class

        @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;
            }   
        }
    • This approach worked fine in Hibernate 4.1.x, but it didn't in EclipseLink 2.x.

    edit

    • As per the comment, it seems to be working with EclipseLink 2.6.1-RC1.
    0 讨论(0)
  • 2020-11-29 07:52

    In JPA that cannot be done with annotations. Annotation itself cannot be overridden. Entity inherits all the mapping information from MappedSuperClass. There is only two annotations that can be used to redefine mappings inherited from mapped superClass:

    1. AttributeOverride to override column mappings and
    2. AssociationOverride to override join columns / table.

    Neither of them helps with GeneratedValue.

    0 讨论(0)
  • 2020-11-29 08:01

    I'm writing this as it gets too unreadable as the comment on the accepted answer:

    I have a BaseEntity that every other Entity inherits from:

    BaseEntity.java:

    @MappedSuperclass
    public abstract class BaseEntity {
    
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ID")
        private Long id;
    

    I then have two Entities User and Order that both inherit from BaseEntity whilst also having the @SequenceGenerator annotation:

    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 { ... }
    

    It works on H2 at least with 2 Sequences SEQ_USER and SEQ_ORDERS:

    select SEQ_USER.nextval from dual;
    select SEQ_ORDERS.nextval from dual;
    
    0 讨论(0)
  • 2020-11-29 08:03

    With EclipseLink, you can use a Customizer. DescriptorCustomizer interface defines a way to customize all the information about a jpa descriptor (aka a persistent entity).

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

    and in your mapped superclass:

    @MappedSuperclass
    @Customizer(SequenceCustomizer.class)
    public abstract class AbstractEntity implements Serializable {
        ...
    }
    
    0 讨论(0)
提交回复
热议问题