Двунаправленная связь со свойством сущности суперкласса в JPA - PullRequest
0 голосов
/ 03 октября 2011

Я пытаюсь реализовать какую-то древовидную структуру с помощью JPA. У меня есть сущность «папка» и сущность «тест». Папка может содержать как папки, так и тесты. Тест не содержит ничего.

Тест и папка имеют суперкласс Node, выглядит так:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Node implements TreeNode, Serializable{

    private Long id;    
    String description;    
    String name;

    @ManyToOne 
    Node parent;

    ...getters, setters and other stuff that doesnt matter...
}

А вот класс Папки:

@Entity
public class Folder extends Node{

    @LazyCollection(LazyCollectionOption.FALSE) 
    @OneToMany(cascade=CascadeType.ALL, **mappedBy="parent"**)
    List<Folder> folders;

    @LazyCollection(LazyCollectionOption.FALSE) 
    @OneToMany(cascade=CascadeType.ALL, **mappedBy="parent"**)
    List<Test> tests;

    ...
}   

Итак, основная проблема - это свойство mappedBy, которое относится к свойству суперкласса, не переопределенному в предке, потому что я получил такое исключение:

Exception while preparing the app : mappedBy reference an unknown target entity property: my.test.model.Folder.parent in my.test.model.Folder.folders

Там может быть какое-то хитрое отображение свойств «папок» и «тест» класса Folder, и мне нужна небольшая помощь в этом.

РЕДАКТИРОВАТЬ: я указал свойства папок и тестов класса Folder с targetEntity = Node.class:

    @LazyCollection(LazyCollectionOption.FALSE) 
    @OneToMany(cascade=CascadeType.ALL, mappedBy="parent",targetEntity=Node.class)
    List<Folder> folders;

    @LazyCollection(LazyCollectionOption.FALSE) 
    @OneToMany(cascade=CascadeType.ALL, mappedBy="parent",targetEntity=Node.class)
    List<Test> tests;

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

Так что я все еще ищу подходящие сопоставления для достижения этого. Я бы оценил любую помощь.

1 Ответ

0 голосов
/ 03 октября 2011

Интересная структура, вероятно, содержит много проблем. Но к вопросу об отношении к свойству сущностей суперкласса: к сожалению, вы не можете сделать это с Hibernate. Ваш подход к установке targetEntityClass также не работает, поскольку он эффективно меняет тип элементов коллекции с точки зрения отображения сущностей.

К счастью, есть обходной путь. Вы можете иметь отношение от сущности к свойству MappedSuperClass, которое вы расширяете. Скорее всего, вы не хотите, чтобы Node был MappedSuperClass, поэтому вы должны добавить новый. И тогда он должен быть расположен между узлом и папкой: папка-> MappedSuperClass-> узел. Это выглядит так (такой подход работает по крайней мере с Hibernate 3.5.6, понятия не имею, с какой версией он поддерживается):

public class Node {
      ... //without parent attribute, otherwise as before
}

@MappedSuperclass
public class SomethingWithParent extends Node {
    @ManyToOne
    Node parent;
}
public class Folder extends SomethingWithParent {
..
//as before
}

public class Test extends SomethingWithParent {
...//as before
}

Кстати, не слишком ли универсален Node для Parent? По крайней мере, если он используется только для этой цели. Все родители являются папками.

...