Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPQL: How to "SELECT new Foo(null, null... someValue, ..)?

For example I have an entity

public class Foo {
   private String col1;
   private String col2;
   private String col3;
   private String col4;

   //getters and setters   
}

What I want to do is to select only col3 and col4. But I already have a Foo constructor like below:

public Foo (String col1, String col2) {
   this.col1 = col1;
   this.col2 = col2;
}

Thus, I cannot have another constructor for col3 and col4 because it will have the same signature.

What I am trying to accomplish so far is to make a complete constructor like:

public Foo (String col1, String col2, String col3, String col4) {
   this.col1 = col1;
   this.col2 = col2;
   this.col3 = col3;
   this.col4 = col4;
}

But when I try to do something like below in my query

SELECT new Foo(null, null, f.col3, f.col4)
FROM Foo f

I get

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected end of subtree

Although when I try

SELECT new Foo(f.col1, f.col2, f.col3, f.col4)
FROM Foo f

It works as expected.

EDIT:

I tried

Select f.col3, col4..

and the error below was thrown

org.springframework.dao.InvalidDataAccessApiUsageException: Cannot create TypedQuery for query with more than one return using requested result type [com.lala.entity.Foo]; nested exception is java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return using requested result type [com.lala.entity.Foo]
like image 737
Rey Libutan Avatar asked Aug 27 '13 04:08

Rey Libutan


1 Answers

You can try (but just a try)

SELECT new Foo(cast(null as string), cast(null as string), f.col3, f.col4)
FROM Foo f

or looking about cast() operator for JPQL if it is supported (I'm not sure)
else

Session session = entityManager.unwrap(Session.class);
List<Foo> list = session.createQuery("select f.col3, f.col4 from Foo f").list()

This is Hibernate specific and you don't need specific constructor for every projections; just create an empty constructor Foo() (at least protected, I don't remember if private is allowed) and let Hibernate inject value into col3, col4 from your query (and cast() operator is supported if your underlying database support the function).

like image 139
Luca Basso Ricci Avatar answered Nov 03 '22 14:11

Luca Basso Ricci