отношение @ManyToOne никогда не читается

#jpa-2.0 #eclipselink

#jpa-2.0 #eclipselink

Вопрос:

Я должен реализовать родительско-дочернее дерево с EclipseLink.

Следующий код компилируется нормально, разумный DDL-код генерируется автоматически, но поле дочерних элементов всегда преобразуется в пустое множество, и трассировка показывает, что для заполнения этого поля никогда не выполнялось никаких запросов.

 @Entity
public class TreeNode {
  @Id @GeneratedValue
  private int id;

  private TreeNode parent;

  @OneToMany(mappedBy="parent")
  private Set<TreeNode> children;
}
  

Комментарии:

1. Можете ли вы поместить код для заполнения дочерних элементов?

2. общедоступный недействительный AddNode (дочерний элемент TreeNode) { дочерний элемент.parent = this; getChildren().add(дочерний элемент); emf.persist(дочерний элемент); }

3. Код, который заполняет базу данных, работает превосходно: я могу прочитать объекты, о которых идет речь, с помощью простого SQL. Странно то, что программа не выдает запросов 🙁

4. Эти запросы выполняются внутренне. Если вы используете mysql, вы можете просмотреть их с помощью MyAdministrator в журнале запросов (после включения опции их отслеживания).

5. Нет, я переключил ведение журнала MySQL на mysqlld, запроса по-прежнему нет 🙁

Ответ №1:

Похоже, что AddNode сохраняет дочерний элемент, но если он не работает с управляемым родительским элементом, ему потребуется объединить родительский элемент, чтобы изменения в коллекции также были сохранены. В противном случае изменения, внесенные в родительский файл, не сохраняются в кэше, и поэтому он не покажет никаких изменений, пока не будет обновлен из базы данных.

Ответ №2:

На самом деле, реальная структура классов не так проста, и это источник проблемы в EclipseLink:

 @Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
abstract class TreeNode {
  @Id int id;
  private TreeNode parent;

  @OneToMany(mappedBy="parent")
  private Set<TreeNode> children;
}

abstract class NamedNode extends TreeNode { String name, title; }

class ConcreteNode1 extends NamedNode { ... some concrete fields }
class ConcreteNode2 extends NamedNode { ... some concrete fields }
....
  

Предполагается, что создаются экземпляры только классов ConcreteNodeXXX, и все они должны наследовать поля name и title из абстрактного класса NamedNode. EclipseLink не жалуется, но не справляется с чтением дочерних элементов из нескольких таблиц.

В конце концов, я переключился в режим гибернации, и пока он хорошо обрабатывает эту конструкцию.

Комментарии:

1. Вы упомянули, что он не запрашивал для дочерних элементов, поэтому я не понимаю, почему на это повлияло бы используемое наследование — все еще кажется, что это было бы больше связано с EclipseLink, использующим кэш второго уровня. Можете ли вы попробовать обновить объект? Если дочерние файлы по-прежнему не читаются, пожалуйста, отправьте сообщение об ошибке в EclipseLink. В противном случае кэш можно отключить, если требуется, или сохранить согласованным путем объединения изменений, как указано.

2. Я просто запустил программу, прочитал родительский объект с помощью запроса и исследовал дочерний слот. Оно содержало неинициализированную коллекцию, которая превращается в пустую коллекцию, как только я вызываю для нее любой метод сбора данных без выполнения какой-либо операции с базой данных. Кстати, если я прочитаю предполагаемые дочерние элементы с другим запросом, все они будут иметь значение NULL в родительском поле 🙁