Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java hibernate/jpa how to create dynamic generic entity that is self related

I would like to create dynamic and generic superclass with JPA/hibernate that will be extended for each hierarchical structured model like: role, page, directory, department, permission, tree. I would like to create with this object dynamic tree using recursion and java reflection

it should look this way:

enter image description here

This entity should have reference to self entity.

I would like it to be completely abstract and had no db table. Only extendet enities should have db.

I've tried to achive this. But fail so long. Here is my post about it

I consider solutions:

  • @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  • @Any and @AnyMetaDef mappings
  • @MappedSuperclass
  • @Embeddable and @Embedded

I hope someone will give some suggestions.

like image 690
masterdany88 Avatar asked Nov 24 '14 12:11

masterdany88


People also ask

What is @ID annotation in Hibernate?

The @Id annotation is inherited from javax.persistence.Id, indicating the member field below is the primary key of the current entity. Hence your Hibernate and spring framework as well as you can do some reflect works based on this annotation.

Is @entity annotation mandatory in Hibernate?

The entity class must be annotated with the Entity annotation or denoted in the XML descriptor as an entity. So, if you use annotations for mappings, @Entity is mandated by the specification and Hibernate has to adhere to it.

What is Generationtype in Hibernate?

SEQUENCE is the generation type recommended by the Hibernate documentation. The generated values are unique per sequence. If we don't specify a sequence name, Hibernate will reuse the same hibernate_sequence for different types.


1 Answers

I came up with the following design. You can also check it on 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);
    }
}

And this is the test:

@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;
        }
    });
}
like image 113
Vlad Mihalcea Avatar answered Oct 18 '22 19:10

Vlad Mihalcea