Search code examples
javahibernatejpajerseyentitymanager

Return partial Entity from EntityManager


JPA-QL states that I should be able to query an Entity with select s.message from Status s, which does works in an JPA-QL console.

However, what I'd really like to do is only return specific properties of the Entity in a return list, like so:

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public List<Status> getIt() {
    EntityManager em = PersistenceManager.INSTANCE.getEntityManager();
    List<Status> results = em.createQuery("select s.message from Status s").getResultList();

    return results;
}

That errors out, though, with no real error message at all. I can see that Hibernate ran this query:

Hibernate: 
    select
        status0_.ID as col_0_0_ 
    from
        LIBRARY.TABLE status0_

A traditional select s from Status s works just fine:

@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public List<Status> getIt() {
    EntityManager em = PersistenceManager.INSTANCE.getEntityManager();
    List<Status> results = em.createQuery("select s from Status s").getResultList();

    return results;
}

Solution

  • If you want only to retrieve one primitive of an entity, getResultList() will return a List<> of this primitive. In your case, if s.message is String, the result type is List<String>.

    However, we often use more than just one element. Typically, we use constructor expressions for that. They are very powerful because we can map queries with joins to one data object or - as in your case - select only the fields we really want.

    Assume a Transfer Object like this:

    public class TO {
        Long id;
        String message;
        public TO(Long id, String message) {
            this.id = id;
            this.message = message;
    }
    

    Then you can create a query (I prefer TypedQueries):

    TypedQuery<TO> qry = em.createQuery("SELECT NEW org.mypackage.TO(s.id, s.message) FROM Status s", TO.class);
    List<TO> myList = qry.getResultList();
    

    Hope this helps!