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;
        }
    });
}
Другие вопросы по тегам