Можно ли добавить JPA-аннотацию к переменным экземпляра суперкласса? - PullRequest
25 голосов
/ 21 мая 2010

Я создаю одинаковые сущности для двух разных таблиц. Для того, чтобы отображения таблиц и т. Д. Отличались для двух сущностей, но оставляли только код в одном месте - абстрактный суперкласс. Лучше всего было бы иметь возможность комментировать общие вещи, такие как имена столбцов (поскольку они будут идентичны) в суперклассе, но это не работает, потому что аннотации JPA не наследуются дочерними классами. Вот пример:

public abstract class MyAbstractEntity {

  @Column(name="PROPERTY") //This will not be inherited and is therefore useless here
  protected String property;


  public String getProperty() {
    return this.property;
  }

  //setters, hashCode, equals etc. methods
}

Который я бы хотел унаследовать и указать только материал для детей, например, аннотации:

@Entity
@Table(name="MY_ENTITY_TABLE")
public class MyEntity extends MyAbstractEntity {

  //This will not work since this field does not override the super class field, thus the setters and getters break.
  @Column(name="PROPERTY") 
  protected String property;

}

Есть идеи или мне нужно будет создавать поля, методы получения и установки в дочерних классах?

Спасибо, Kris

Ответы [ 4 ]

26 голосов
/ 21 мая 2010

Возможно, вы захотите аннотировать MyAbstractEntity с помощью класса @MappedSuperclass, чтобы hibernate импортировал конфигурацию MyAbstractEntity у дочернего элемента, и вам не пришлось переопределять поле, просто используйте родительский. Эта аннотация является сигналом для спящего режима о том, что она также должна проверить родительский класс. В противном случае он предполагает, что может игнорировать его.

13 голосов
/ 29 января 2013

Вот пример с некоторыми пояснениями, которые могут помочь.

@ MappedSuperclass:

  • это удобный класс
  • Используется для хранения общего состояния и поведения, доступных для дочерних классов
  • Не является устойчивым
  • Только дочерние классы являются постоянными

@ Наследование задает одну из трех стратегий отображения:

  1. однотабличные
  2. Таблица на класс

@ DiscriminatorColumn используется для определения того, какой столбец будет использоваться для различения дочерних объектов.

@ DiscriminatorValue используется для указания значения, которое используется для различения дочернего объекта.

Следующий код приводит к следующему:

enter image description here

Вы можете видеть, что поле id находится в обеих таблицах, но указывается только в AbstractEntityId @ MappedSuperclass.

Кроме того, @DisciminatorColumn отображается как PARTY_TYPE в таблице Party.

@DiscriminatorValue отображается как Персона как запись в столбце PARTY_TYPE таблицы Party.

Очень важно, что класс AbstractEntityId вообще не сохраняется.

Я не указал аннотации @Column и вместо этого просто полагаюсь на значения по умолчанию.

Если бы вы добавили сущность организации, которая расширила Сторону, и если бы она сохранялась следующей, то таблица Стороны имела бы:

  • id = 2
  • PARTY_TYPE = "Организация"

Первая запись таблицы организации будет иметь:

  • id = 2
  • другое значение атрибута, связанное конкретно с организациями

    @MappedSuperclass
    @SequenceGenerator(name = "sequenceGenerator", 
            initialValue = 1, allocationSize = 1)
    public class AbstractEntityId implements Serializable {

        private static final long serialVersionUID = 1L;

        @Id
        @GeneratedValue(generator = "sequenceGenerator")
        protected Long id;

        public AbstractEntityId() {}

        public Long getId() {
            return id;
        }
    }

    @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    @DiscriminatorColumn(name = "PARTY_TYPE", 
            discriminatorType = DiscriminatorType.STRING)
    public class Party extends AbstractEntityId {

        public Party() {}

    }

    @Entity
    @DiscriminatorValue("Person")
    public class Person extends Party {

        private String givenName;
        private String familyName;
        private String preferredName;
        @Temporal(TemporalType.DATE)
        private Date dateOfBirth;
        private String gender;

        public Person() {}

        // getter & setters etc.

    }

Надеюсь, это поможет:)

3 голосов
/ 21 мая 2010

Пометить суперкласс как

@MappedSuperclass

и удалите свойство из дочернего класса.

2 голосов
/ 21 мая 2010

Аннотирование вашего базового класса с помощью @MappedSuperclass должно делать именно то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...