41

Hey everyone, I'm new to persistence / hibernate and I need your help.

Here's the situation. I have a table that contains some stuff. Let's call them Persons. I'd like to get all the entries from the database that are in that table.

I have a Person class that is a simple POJO with a property for each column in the table (name, age,..)

Here's what I have :

Query lQuery = myEntityManager.createQuery("from Person")
List<Person> personList = lQuery.getResultList();

However, I get a warning saying that this is an unchecked conversion from List to List<Person>

I thought that simply changing the code to

Query lQuery = myEntityManager.createQuery("from Person")
List<Person> personList = (List<Person>)lQuery.getResultList();

would work.. but it doesn't.

Is there a way to do this ? Does persistence allow me to set the return type of the query ? (Through generics maybe ? )

GuiSim
  • 7,361
  • 6
  • 40
  • 50

5 Answers5

87

As a newcomer to JPA was taking this as the definitive answer but then I found a better one via this question: Why in JPA EntityManager queries throw NoResultException but find does not?

Its as simple as as using TypedQuery instead of Query e.g.:

TypedQuery<Person> lQuery = myEntityManager.createQuery("from Person", Person.class);
List<Person> personList = lQuery.getResultList();
Community
  • 1
  • 1
Bruce Adams
  • 4,953
  • 4
  • 48
  • 111
  • `Query` is an abstract type, so it can still be a `Query` here if you really want it. I prefer the one line implementation anyway: ``` List personList = myEntityManager.createQuery("from Person", Person.class).getResultList(); ``` – aarowman Mar 23 '21 at 21:54
10

Note: This answer is outdated as of JPA 2.0, which allows you to specify the expected type. See this answer.


Suppressing the warning with

@SuppressWarnings("unchecked")
List<MyType> result = (List<MyType>) query.getResultList();

is the only solution to this problem I have ever seen. The suppression is ugly, but you can trust JPA to return the right type of object, so there is no need to check manually.

If you use polymorphisms and don't know the exact result type, the use of Generics with a bounded Class parameter is also a common pattern:

public List<T extends MyBaseType> findMyType(Class<T> type) {
    @SuppressWarnings("unchecked")
    List<T> result = (List<T>) this.entityManager.createQuery(
        "FROM " + type.getName())
        .getResultList();
    return result;
}
Community
  • 1
  • 1
Henning
  • 16,063
  • 3
  • 51
  • 65
4

Well there is the java Collections class solution, but you didn't explain how your casting was failing, or if it was just giving a warning...

This is one way to validate this:

Collections.checkList(lQuery.getResultList(), Person.class);

But if you don't need to validate it:

@SuppressWarnings("unchecked") List<Person> personList = lQuery.getResultList();
Petriborg
  • 2,940
  • 3
  • 28
  • 49
  • I didn't explain how my casting was failing because it is not failing. It simply doesn't silence the Warning.. so it doesn't do anything. – GuiSim Jun 05 '09 at 19:36
2

Alternative way:

Query query = entityManager.createNativeQuery("SELECT * FROM person", Person.class);
List<Person> rows = query.getResultList();
ukchaudhary
  • 377
  • 3
  • 7
  • while doing (rows.get(0) instanceof Person) . you may get "false". ( not in case of simple select statements like this). Please go to https://stackoverflow.com/a/13701011/4959470 – RAHUL ROY Apr 02 '18 at 11:01
1

I've been stuck with this problem for a while, too. You can iterate over the list, and check, but I'd prefer less noise. The shortest way I have seen getting around this is to silence the warning, but I am also very uncomfortable with that. I'd be interested to see other solutions.

@SuppressWarnings("unchecked") 
List<Person> personList = lQuery.getResultList();

Hmm, while researching I found an interesting post on java.net. I found the user comments particularly interesting.

Charlie
  • 216
  • 1
  • 3