#java #jpa #eclipselink
#java #jpa #eclipselink
Вопрос:
Я пытаюсь использовать внутренний класс как встраиваемый для представления некоторых сложных свойств внешнего класса. Когда я сохраняю это, в схеме базы данных, сгенерированной eclipselink, нет информации из внутреннего класса.
Кажется ли хорошей идеей то, что я пытаюсь сделать? Почему eclipselink, похоже, не распознает их @Basic
атрибут в getRate()
в Attributes
?
Некоторая другая информация: Measure
должен быть создан экземпляр с использованием фабрики, которая предоставляется конструктору Person
, поэтому я даже не знаю, как я вообще смогу это использовать. Кажется все более вероятным, что мне придется создать отдельный класс просто для хранения состояния Person
в простых терминах (например, doubles, не Measures
) и использовать их для создания объектов реального Person
типа, но это имеет очень печальные последствия для остальной части моего приложения.
@Entity
public static class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Transient
public Measure<Double, CleanupRate> rate;
@Embedded
private Attributes attributes;
@Embeddable
public static class Attributes {
@Transient
private Person person;
public Attributes() {
}
public Attributes(Person person) {
this.person = person;
}
@Basic
public double getRate() {
return person.rate.getInternalValue();
}
public void setRate(double value) {
person.rate.setInternalValue(value);
}
}
public Person() {
rate = udm.getMeasureFactory().createMeasure(0.0, CleanupRate.class);
attributes = new Attributes(this);
}
public void setRate(double rate) {
this.rate.setValue(rate);
}
}
Редактировать:
Чтобы внедрить зависимость меры в мои объекты, когда они извлекаются из хранилища, я добавил интерфейс, который внедряет зависимость, и использовал его в моем DAO. Поскольку DAO может быть внедрен, я могу распространить зависимость вплоть до извлекаемых объектов. Я почерпнул идею из блога.
private <T extends UomInjectable> List<T> //
getListOfUomInjectableType(final Class<T> klass) {
List<T> result = getListOfType(klass);
for (UomInjectable injectable : result) {
injectable.injectUomFactory(udm);
}
return resu<
}
Ответ №1:
Он использует тип доступа из класса Person, для которого задано значение field , и поэтому не видит аннотацию на уровне свойств.
Вам нужно будет изменить тип доступа, используя Access (СВОЙСТВО) для встраиваемого класса, и следует удалить аннотацию @Transient в атрибуте person.
Ответ №2:
Я думаю, что в целом у вас возникнут проблемы с объектами (встраиваемыми или иными), которым нужны конструкторы с аргументами. Я не уверен, как это может быть связано с вашей проблемой генерации схемы, но я думаю, что это будет проблемой при попытке сохранить / извлечь эти объекты.
Как вы намекнули, JPA требует, чтобы все типы сущностей имели конструктор без аргументов. Хотя в вашем классе атрибутов есть один, он оставляет поле ‘person’ равным null, что довольно быстро приведет к NPE. То же самое с конструктором Person (возможно, вы пропустили тот, который передается в ‘udm’ из примера кода?).
Комментарии:
1. Да, это просто тестовый код внутри модульного теста (вот почему Person статичен), поэтому
udm
определен в тестовом классе.2. Я смог обойти наличие ссылки на
Person
внутренние атрибуты, используя@PostLoad
метод внутриPerson
, который считывает значения из объекта attributes. Все еще думаю о том, как я собираюсь создавать экземплярыMeasure
объектов, не прибегая к Singleton.
Ответ №3:
Чтобы задать Person для атрибутов, просто используйте property access лично и задайте его в вашем методе SetAttributes.
Смотрите, http://en.wikibooks.org/wiki/Java_Persistence/Embeddables#Relationships