Подтвердить что ты не робот

Можно ли добавить аннотацию JPA к переменным экземпляра суперкласса?

Я создаю сущности, которые одинаковы для двух разных таблиц. Для того, чтобы сопоставления таблиц и т.д. Отличались для двух объектов, но только остальная часть кода в одном месте - абстрактный суперкласс. Лучше всего было бы уметь комментировать общие вещи, такие как имена столбцов (поскольку они будут идентичными) в суперклассе, но это не работает, потому что аннотации 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

4b9b3361

Ответ 1

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

Ответ 2

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

@MappedSuperclass:

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

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

  • однотабличные
  • Регистрация
  • Таблица для класса

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

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

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

enter image description here

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

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

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

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

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

Если вы добавили объект Organization, который расширил Сторону, и если это было сохранено дальше, тогда таблица Party будет иметь:

  • 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

Отметьте суперкласс как

@MappedSuperclass

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

Ответ 4

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