Reputation: 68972
In my current project I need to perform a few native queries which pick some fields from tables joined in the query e.g.:
SELECT t1.col1, t2.col5
FROM t1
JOIN t2 ON t2.id = t1.t2_id
I tried to store them in a class like
class Result {
String t1_col1;
String t2_col5;
}
using
Query q = entityManager.createNativeQuery( "THE SQL SELECT" , Result.class );
JPA now complains ("uknown entity: result") that the class 'result' isn't an entity which is probably required to map the columns into the object.
I also tried to repeat the @Column
declarations in the result class.
My question is how can I declare this without having to create the entites represented as tables in my DB?
Upvotes: 6
Views: 3153
Reputation: 15577
I can run that query (with a slight change) in DataNucleus JPA and it works fine, as it should per the JPA spec.
SELECT t1.col1 AS t1_col1, t2.col5 AS t2_col5 FROM t1 JOIN t2 ON t2.id = t1.t2_id
i.e make the return columns line up with the field names in the result class. The JPA spec does not say that the result class has to be an Entity class; it simply says "the class of the resulting instance(s)".
Upvotes: 1
Reputation: 691943
If you're using JPA/Hibernate to perform SQL queries, then you're using the wrong tool. Hibernate is an ORM, and you're supposed to map tables to entities. That's the whole point of JPA. I you just want to perform SQL queries, use JDBC (and Spring's JdbcTemplate for example)
Once table1 and table2 are mapped to entities (let's call these entities T1 and T2), you won't need these SQL queries anymore, because JPQL is able to select only some fields of the entities. Your query could the look like this (depending on the association between t1 and t2):
select t1.col1, t2.col5 from T1 t1 join t1.t2 t2
And you would just have to iterate over the result (a list of Object[]) to build your results (which is a DTO and not a mapped entity) :
List<Object[]> rows = (List<Object[]>) query.list();
List<Result> listOfResults = new ArrayList<Result>(rows.size);
for (Object[] row : rows) {
listOfResults.add(new Result((String) row[0], (String) row[1]));
}
Upvotes: 5
Reputation: 23373
You might get away with defining a VIEW which returns the joined columns needed from its queries and use the view name for your dataholder class.
Upvotes: 0
Reputation: 597234
Alas, I don't see a way to do it in JPA. However, you can do it with the hibernate Query
object. to obtain it use:
org.hibernate.Query query = q.unwrap(org.hibernate.Query.class);
And then set a result transformer. See here:
query.setResultTransformer(Transformers.aliasToBean(Result.class));
Upvotes: 6