简体   繁体   中英

MappedSuperclass - Change SequenceGenerator in Subclass

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

However, for every table theres a sequence $entityname_seq which I want to use as my sequence generator. How can I set that from my subclass? I think I need to override @GeneratedValue and create a new SequenceGenerator with @SequenceGenerator.

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.

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.

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

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM