Reputation: 5314
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]
Upvotes: 13
Views: 12076
Reputation: 183
I know this question is old but you can also do (if cast didn't work for you):
String query = "select new Pojo( " +
" trim(:null), " +
" trim(:null), " +
" f.col3, " +
" f.col4 " +
" ) " +
" from Foo as f ";
return em.createQuery(query, Pojo.class)
.setParameter("null", null)
.getResultList();
Edited: JPA ignores literal columns when mapping them to the constructor arguments, so wrapped with trim to let JPA aware of the literal value.
Upvotes: 5
Reputation: 18403
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).
Upvotes: 11