Java Hibernate/ JPA, как создать динамический универсальный объект, который сам по себе
Я хотел бы создать динамический и универсальный суперкласс с JPA/hibernate, который будет расширен для каждой иерархической структурированной модели, такой как: роль, страница, каталог, отдел, разрешение, дерево. Я хотел бы создать с этим объектом динамическое дерево, используя рекурсию и Java-отражение
это должно выглядеть так:
Эта сущность должна иметь ссылку на собственную сущность.
Я хотел бы, чтобы он был полностью абстрактным и не имел таблицы БД. Только расширения должны иметь БД.
Я пытался достичь этого. Но терпеть неудачу так долго. Вот мой пост об этом
Я рассматриваю решения:
- @Inheritance (стратегии = InheritanceType.TABLE_PER_CLASS)
- Сопоставления @Any и @AnyMetaDef
- @MappedSuperclass
- @Embeddable и @Embedded
Я надеюсь, что кто-то даст некоторые предложения.
1 ответ
Решение
Я придумал следующий дизайн. Вы также можете проверить это на GitHub:
@MappedSuperclass
public abstract class GenericHierarchicalDictionary {
public abstract GenericHierarchicalDictionary getParent();
public abstract Set<? extends GenericHierarchicalDictionary> getChildren();
}
@Entity
@Table(name = "LocalFolder")
public class LocalFolder extends GenericHierarchicalDictionary {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@ManyToOne
private LocalFolder parent;
@OneToMany(mappedBy = "parent")
private Set<LocalFolder> children = new HashSet<LocalFolder>();
@Override
public LocalFolder getParent() {
return parent;
}
@Override
public Set<LocalFolder> getChildren() {
return children;
}
public void addChild(LocalFolder localFolder) {
localFolder.parent = this;
children.add(localFolder);
}
}
@Entity
@Table(name = "RemoteFolder")
public class RemoteFolder extends GenericHierarchicalDictionary {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@ManyToOne
private RemoteFolder parent;
@OneToMany(mappedBy = "parent")
private Set<RemoteFolder> children = new HashSet<RemoteFolder>();
@Override
public RemoteFolder getParent() {
return parent;
}
@Override
public Set<RemoteFolder> getChildren() {
return children;
}
public void addChild(RemoteFolder localFolder) {
localFolder.parent = this;
children.add(localFolder);
}
}
И это тест:
@Test
public void testTree() {
LOGGER.debug("testAddWebResource");
doInTransaction(new TransactionCallable<Void>() {
@Override
public Void execute(Session session) {
LocalFolder rootLocalFolder = new LocalFolder();
session.persist(rootLocalFolder);
LocalFolder localFolder1 = new LocalFolder();
rootLocalFolder.addChild(localFolder1);
session.persist(localFolder1);
LocalFolder localFolder11 = new LocalFolder();
localFolder1.addChild(localFolder11);
session.persist(localFolder11);
RemoteFolder rootRemoteFolder = new RemoteFolder();
session.persist(rootRemoteFolder);
RemoteFolder remoteFolder1 = new RemoteFolder();
rootRemoteFolder.addChild(remoteFolder1);
session.persist(remoteFolder1);
RemoteFolder remoteFolder11 = new RemoteFolder();
remoteFolder1.addChild(remoteFolder11);
session.persist(remoteFolder11);
return null;
}
});
}