MappedSuperclass - изменить SequenceGenerator в подклассе - PullRequest
26 голосов
/ 21 декабря 2011

Я использую 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.

Ответы [ 3 ]

30 голосов
/ 28 августа 2012

Да, это возможно.Имя генератора по умолчанию можно переопределить с помощью аннотации @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.

edit

  • Согласно комментарию, похоже, что он работает с EclipseLink 2.6.1-RC1.
12 голосов
/ 17 июля 2012

В JPA это невозможно сделать с аннотациями. Сама аннотация не может быть переопределена. Сущность наследует всю информацию сопоставления от MappedSuperClass . Существует только две аннотации, которые можно использовать для переопределения отображений, унаследованных от сопоставленного суперкласса:

  1. AttributeOverride для переопределения сопоставлений столбцов и
  2. AssociationOverride для переопределения соединяемых столбцов / таблицы.

Ни один из них не помогает с GeneratedValue.

4 голосов
/ 11 сентября 2015

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