Leader and led logic with recursion in Java

2

I'm having a relatively simple problem to solve, but I'm not getting a logical disability. My problem is this:

I have a hierarchy of leaders and leaders. For example:

Lider 1
    Lider 1.1
        Lider 1.1.1
        Lider 1.1.2
        Lider 1.1.3
            Lider 1.1.3.1
    Lider 1.2
        Lider 1.2.1
    Lider 1.3

And so it goes. How many levels are needed. In the database, this is already mapped. That is, I can tell who is leading who using the following sample query:

select * from colaboradores where lider_id = ?;

However, I am not able to build an efficient Java recursion to return all the leaders below. For example, if I pass to my method the ID of the leader 1.1, should it return to me a list like this:

Lider 1.1
Lider 1.1.1
Lider 1.1.2
Lider 1.1.3
Lider 1.1.3.1

Does anyone have a light for me there?

UPDATE: I tried to map JPA itself. Just a note: The relationship between leaders and leaders is not done via the class ID, but rather another field that is not a foreign key. This other field is tuition. See:

@ManyToOne(targetEntity = Colaborador.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "matricula_lider", referencedColumnName = "matricula", insertable = false, updatable = false)
private Colaborador lider;

@OneToMany(mappedBy="lider", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
private List<Colaborador> liderados;

Well, if I use only the mapping:

@ManyToOne(targetEntity = Colaborador.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "matricula_lider", referencedColumnName = "matricula", insertable = false, updatable = false)
private Colaboradorlider;

It works cool and I get the leader of the person. If I use both mappings (bi-directional), the error when trying to recover. In fact, it does not give an error, it seems that it goes into an infinite loop until the timeout of the transaction.

javax.persistence.PersistenceException: org.hibernate.HibernateException: Transaction was rolled back in a different thread!
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)

...

Is my mapping wrong?

    
asked by anonymous 03.09.2014 / 16:11

2 answers

2

Considering that your hierarchy in the database is mapped using a foreign key that points to the class itself,

You can do the same concept in java:

class Pessoa {
   Pessoa lider;
   List<Pessoa> colaboradores;
}

One person is a leader if one has collaborators, and one person's leader is another person. This is recursive, but you will have a challenge that is to transform from Object to Relational and vice versa.

If you use hibernate it will take care of this problem:

@Entity
class Pessoa {
@ManyToOne
Pessoa lider;
@OneToMany(mappedBy="lider", fetch=FetchType.LAZY )
List<Pessoa> colaboradores;
}

And then using a JQL

EntityManager em;
// Obtem o entitymanager conforme o padrão usado, JTA ou RESOURCE_LOCAL
em.createQuery("select p from Pessoa p where p.lider = :lider_id").setParam("lider_id", 2).getResultList(); // Retorna uma lista de Pessoas
    
03.09.2014 / 17:40
3

There are different techniques for modeling a hierarchical structure in a relational database, as can be seen in the question:

  

How to model a tree structure using a relational database?

The most straightforward but painless solution to performance is to use a criterion with like . Example:

select * from colaboradores where lider_id like ? || '%'; -- oracle
select * from colaboradores where lider_id like ? + '%'; -- sql server

Note: The lider_id field is considered to be a VARCHAR or VARCHAR2 .

This solution does not look so bad if there is an index created for the lider_id field, ensuring that the RDBMS does not need to read the entire table .

Indexes in text columns work up to a certain number of characters and do not use '%' at the beginning, but only at the end of the search criteria.

    
03.09.2014 / 17:00