How to obtain entities and their relationships using Hibernate?

0

I am working with Spring 4 and Hibernate 5. I am doing a test application to manage the events of a fictional theater, and also keep information about those events. I have several classes annotated with @Entity, such as Theater, User, Seat, Room, etc., and many of these classes are related to each other. These classes are already in my database as tables and have stored information.

Now I need to show in my program the amount of entities I have and the relationships between them. But I do not know how to map the database to obtain my entities and their relationships.

I need a method or procedure that returns these values, for example these would be the final results:

Object[] entidades ={Teatro, Sala, Asiento, Persona}
String[] relaciones ={Teatro-Sala, Sala-Asiento, Teatro-Asiento, Asiento-Persona}

Since I use Hibernate and my classes are annotated with @Entity, I've searched for some way to get the information I want but I can not find how to do it. So, in what way can I get my entities and the relationships between them?

Keep in mind that some of the entities can be eliminated eventually, therefore it would be necessary to update the amounts of entities and relationships between them

EDITED

Here I add the code of my DAO, to illustrate an example of how to save it in the database:

@Repository
public class PersonDAOImpl implements PersonDAO {

    private static final Logger logger = LoggerFactory.getLogger(PersonDAOImpl.class);

    @Autowired
    private SessionFactory sessionFactory;


    @Override
    @Transactional
    public void addPerson(Person p) {
        Session session = this.sessionFactory.getCurrentSession();
        session.persist(p);
        logger.info("Person saved successfully, Person Details="+p);
    }
    
asked by Ethan 22.03.2017 в 15:47
source

2 answers

1

EDIT: this response is applicable until hibernate 5.1. From 5.2 you have to start from EntityManagerFactory#getMetamodel() .

The list of entities managed by hibernate is obtained with:

Map<String,ClassMetadata> mapEntidades = this.sessionFactory.getAllClassMetadata();

where the key of the map is the full name of the entity. The simple name of each entity can be obtained by iterating over the map with:

AbstractEntityPersister persister = (AbstractEntityPersister) entry.getValue();
String nombreEntidad = persister.getEntityType().getReturnedClass().getSimpleName();

The list of relationships that are OneToMany or ManyToMany you get with:

Map<String,CollectionMetadata> mapRelaciones =  this.sessionFactory.getAllCollectionMetadata();

and you can get the names of the related entities by iterating over the map with:

AbstractCollectionPersister cp = (AbstractCollectionPersister) entry.getValue();
String entidadPrincipal = cp.getOwnerEntityPersister().getEntityMetamodel().getEntityType().getReturnedClass().getSimpleName();
String entidadRelacionada = cp.getElementNodeName();

ManyToOne relationships are obtained from the ClassMetadata of the first map. You have to get the array of types of the entity and look for the class ManyToOneType :

Type[] tipos = persister.getClassMetadata().getPropertyTypes();
for (Type t : tipos) {
    if (t instanceof ManyToOneType) {
        ManyToOneType mtot = (ManyToOneType) t;
        String entidadRelacionada = mtot.getReturnedClass().getSimpleName();
        ...
    }
}
    
answered by 29.03.2017 в 16:30
0

After doing several tests, these are the solutions to which it arrives. I leave the codes of the two methods I did. I still have the thorn with the obsolete methods, I would appreciate suggestions about this.

Method to obtain the entities:

@SuppressWarnings("rawtypes")
    public void listarEntidades(){
        @SuppressWarnings("deprecation")
        Set<EntityType<?>> entidades = sf.getMetamodel().getEntities();
        List<String> listEntities = new ArrayList<>();
          for (javax.persistence.metamodel.EntityType<?> entidad: entidades) {
              listEntities.add(new String(((EntityTypeImpl) entidad).getTypeName()));         
              }

          System.out.println("Printing entities");
          for(String x:listEntities){
              System.out.println("Entity name: "+x);
          }
    }

Method to obtain the attributes:

@SuppressWarnings("unchecked")
    public void listarAtributos(){
        @SuppressWarnings("deprecation")
        Set<EntityType<?>> entidades = sf.getMetamodel().getEntities();
        //Set<?> listEntities;
        Set<PluralAttribute<?, ?, ?>> plural;
        Set<SingularAttributeImpl<?, ?>> single;
        for (@SuppressWarnings("rawtypes") javax.persistence.metamodel.EntityType entidad : entidades) {
            plural = entidad.getDeclaredPluralAttributes();
            single = entidad.getSingularAttributes();
            System.out.println("****************************************");
            System.out.println(entidad.getName());
            for (PluralAttribute<?, ?, ?> x : plural) {
                System.out.println(x.getName() + "__" + x.getBindableJavaType());
            }
            for (SingularAttributeImpl<?, ?> x: single){
                System.out.println(x.getName() + "__" +x.getBindableJavaType());
            }
            }

Result printed on the console:

Entity name: com.pavel.model.Band
Entity name: com.pavel.model.ConcertHall
Entity name: com.pavel.model.Ticket
Entity name: com.pavel.model.Payment
Entity name: com.pavel.model.Seat
Entity name: com.pavel.model.Concert
Entity name: com.pavel.model.Customer
Entity name: com.pavel.model.Booking
****************************************
Band
concert__class com.pavel.model.Concert
address__class java.lang.String
bandName__class java.lang.String
activeSince__class java.lang.String
bandId__int
****************************************
ConcertHall
concerts__class com.pavel.model.Concert
seats__class com.pavel.model.Seat
address__class java.lang.String
hallId__int
hallName__class java.lang.String
****************************************
Ticket
seat__class com.pavel.model.Seat
booking__class com.pavel.model.Booking
ticketId__int
concert__class com.pavel.model.Concert
price__float
****************************************
Payment
paymentId__int
amount__float
booking__class com.pavel.model.Booking
****************************************
Seat
ticket__class com.pavel.model.Ticket
seatId__int
seatNumber__int
concertHall__class com.pavel.model.ConcertHall
seatRow__int
****************************************
Concert
bands__class com.pavel.model.Band
tickets__class com.pavel.model.Ticket
concertId__int
startTime__class java.lang.String
concertDate__class java.lang.String
concertHall__class com.pavel.model.ConcertHall
****************************************
Customer
customerBirthDate__class java.lang.String
customerName__class java.lang.String
customerAddress__class java.lang.String
customerId__int
booking__class com.pavel.model.Booking
****************************************
Booking
tickets__class com.pavel.model.Ticket
payment__class com.pavel.model.Payment
customer__class com.pavel.model.Customer
totalPrice__float
bookingId__int

Relations between classes I can infer because the attributes tell me which entity the printed entity relates to. I hope these solutions work for you.

    
answered by 30.03.2017 в 17:55