Использование вложенного вложенного класса для представления сложного состояния в JPA - PullRequest
2 голосов
/ 09 ноября 2011

Я пытаюсь использовать внутренний класс как встраиваемый для представления некоторых сложных свойств внешнего класса. Когда я сохраняю это, отсутствует информация из внутреннего класса в схеме базы данных, сгенерированной eclipselink.

То, что я пытаюсь сделать, кажется хорошей идеей? Почему eclipselink, похоже, не распознает их @Basic атрибут getRate() in Attributes?

Некоторая другая информация: Measure должен быть создан с использованием фабрики, которая предоставляется конструктору Person, поэтому я даже не знаю, как я вообще смогу использовать это. Кажется все более и более вероятным, что мне придется создать отдельный класс просто для хранения состояния Person в простых терминах (например, double, а не 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);
    }
  }

Edit:

Чтобы добавить зависимость меры в мои объекты, когда они извлекаются из хранилища, я добавил интерфейс, который вводит зависимость, и использовал его в моем 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 result;
  }

Ответы [ 3 ]

2 голосов
/ 09 ноября 2011

Он использует тип доступа из класса Person, для которого установлено значение field, и поэтому не видит аннотации на уровне свойств.

Вам необходимо изменить тип доступа с помощью Access (PROPERTY)на встраиваемом классе и должен удалить аннотацию @Transient для атрибута person.

2 голосов
/ 09 ноября 2011

Я думаю, что в целом у вас будут проблемы с сущностями (встраиваемыми или иными), которым нужны конструкторы с аргументами. Я не уверен, как это может быть связано с вашей проблемой генерации схемы, но я думаю, что это будет проблемой при попытке сохранить / извлечь эти объекты.

Как вы намекнули, JPA требует, чтобы все типы сущностей имели конструктор без аргументов. В то время как у вашего класса Attributes он есть, он оставляет поле 'person' пустым, что довольно быстро приведет к появлению NPE. То же самое с конструктором Person (может быть, вы пропустили тот, который передается в 'udm' из примера кода?).

0 голосов
/ 09 ноября 2011

Установите Person для Атрибутов, просто используйте доступ к свойству в Person и установите его в своем методе setAttributes.

См., http://en.wikibooks.org/wiki/Java_Persistence/Embeddables#Relationships

...