Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically set List<type>

I have previously only used reflection to do things like dynamically get class and set field values in it. My Google search showed me that I could also possibly use reflection for dynamic type casting?

My code is as follows:

import entity.Shipvia;
import entity.Route;
import java.lang.reflect.Field;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class RetrieveResultList {

    public static List retrieveResultList(String tablename) {
        EntityManager entityManager = Persistence.createEntityManagerFactory("EntityLibraryPU").createEntityManager();
        Query query = entityManager.createNamedQuery(tablename + ".findAll");
        List<Shipvia> resultList = query.getResultList();
        return resultList;
    }
}

I am using this method to dynamically retrieve result from a database table. Because the table name is always different, I cannot have List as it will be different for each table.

How would I go about converting the tablename string that I am passing in, to be the type of the List?

like image 646
Metal Wing Avatar asked May 28 '12 15:05

Metal Wing


1 Answers

You can't do that and even if you could, it would be useless as all generics information is removed from the Java code when it's compiled, only casts would be there and as you would be using reflection there would be no casts to be made.

The closest thing you will be able to do is, instead of sending in a String send a Class object. The caller code would have to say which class it wants (the caller probably knows what kind of object it's using) and you would use it to make the list have the correct generic.

A very simple implementation would be something like this:

List<Shipvia> shipvias = RetrieveResultList.retrieveResultList( Shipvia.class );

And implementation could be something like this:

public class RetrieveResultList {

    private static final EntityManagerFactory FACTORY = Persistence.createEntityManagerFactory("EntityLibraryPU");

    public static <T> List<T> retrieveResultList(Class<T> type) {
        EntityManager entityManager = FACTORY.createEntityManager();
        String tablename = type.getName(); // figure out table name from **type**
        Query query = entityManager.createNamedQuery(tablename + ".findAll");
        List<T> resultList = query.getResultList();
        entityManager.close();
        return resultList;
    }
}

And then you should have something like what you're looking for.

ALSO, DO NOT create an entity manager factory on every call to this method, the entity manager factory MUST BE a singleton in your project as it's a very expensive object to create. You should also close the EntityManager you created before leaving the method.

like image 60
Maurício Linhares Avatar answered Sep 23 '22 19:09

Maurício Linhares