I am using JPA in my project.
I came to a query in which I need to make join operation on five tables. So I created a native query which returns five fields.
Now I want to convert the result object to java POJO class which contains the same five Strings.
Is there any way in JPA to directly cast that result to POJO object list ??
I came to the following solution ..
@NamedNativeQueries({
@NamedNativeQuery(
name = "nativeSQL",
query = "SELECT * FROM Actors",
resultClass = db.Actor.class),
@NamedNativeQuery(
name = "nativeSQL2",
query = "SELECT COUNT(*) FROM Actors",
resultClass = XXXXX) // <--------------- problem
})
Now here in resultClass, do we need to provide a class which is actual JPA entity ? OR We can convert it to any JAVA POJO class which contains the same column names ?
Not sure if this fits here, but I had similar question and found following simple solution/example for me:
In my case I had to use SQL parts defined in Strings somewhere else, so I could not just use NamedNativeQuery.
I have found a couple of solutions to this.
Using Mapped Entities (JPA 2.0)
Using JPA 2.0 it is not possible to map a native query to a POJO, it can only be done with an entity.
For instance:
But in this case,
Jedi
, must be a mapped entity class.An alternative to avoid the unchecked warning here, would be to use a named native query. So if we declare the native query in an entity
Then, we can simply do:
This is safer, but we are still restricted to use a mapped entity.
Manual Mapping
A solution I experimented a bit (before the arrival of JPA 2.1) was doing mapping against a POJO constructor using a bit of reflection.
This method basically takes a tuple array (as returned by native queries) and maps it against a provided POJO class by looking for a constructor that has the same number of fields and of the same type.
Then we can use convenient methods like:
And we can simply use this technique as follows:
JPA 2.1 with @SqlResultSetMapping
With the arrival of JPA 2.1, we can use the @SqlResultSetMapping annotation to solve the problem.
We need to declare a result set mapping somewhere in a entity:
And then we simply do:
Of course, in this case
Jedi
needs not to be an mapped entity. It can be a regular POJO.Using XML Mapping
I am one of those that find adding all these
@SqlResultSetMapping
pretty invasive in my entities, and I particularly dislike the definition of named queries within entities, so alternatively I do all this in theMETA-INF/orm.xml
file:And those are all the solutions I know. The last two are the ideal way if we can use JPA 2.1.
Unwrap procedure can be performed to assign results to non-entity(which is Beans/POJO). The procedure is as following.
The usage is for JPA-Hibernate implementation.
Use
DTO Design Pattern
. It was used inEJB 2.0
. Entity was container managed.DTO Design Pattern
is used to solve this problem. But, it might be use now, when the application is developedServer Side
andClient Side
separately.DTO
is used whenServer side
doesn't want to pass/returnEntity
with annotation toClient Side
.DTO Example :
PersonEntity.java
PersonDTO.java
DTOBuilder.java
EntityBuilder.java <-- it mide be need
JPA provides an
SqlResultSetMapping
that allows you to map whatever returns from your native query into an Entityor a custom class.EDIT JPA 1.0 does not allow mapping to non-entity classes. Only in JPA 2.1 a ConstructorResult has been added to map return values a java class.
Also, for OP's problem with getting count it should be enough to define a result set mapping with a single
ColumnResult
if you are using Spring, you can use
org.springframework.jdbc.core.RowMapper
Here is an example: