Reputation: 551
My requirement is say I have two table:
T1: id,name,email
T2: id,address
To get data from both table I have done like:
Collection ls=null;
EntityManager em=ConnectionUtils.getEntityManager();
tx= em.getTransaction();
tx.begin();
Query q=em.createQuery("select t1.name,t2.address from T1 t1, T2 t2");
ls=(List<T1T2>)q.getResultList();
OP:[[Ljava.lang.Object;@e836bd1, [Ljava.lang.Object;@561b6dc8, [Ljava.lang.Object;@22c491a2, [Ljava.lang.Object;@17353483, [Ljava.lang.Object;@260a905c, [Ljava.lang.Object;@7f8b9b86, [Ljava.lang.Object;@268fbbd5, [Ljava.lang.Object;@2674b0ba, [Ljava.lang.Object;@36fe970f, [Ljava.lang.Object;@46f75fe, [Ljava.lang.Object;@31ab78f8, [Ljava.lang.Object;@7092fb41, [Ljava.lang.Object;@41ada224, [Ljava.lang.Object;@6e700b2b]
ya its annoying. I am getting data but its an normal Object.
I have created pojo as:
T1T2: String name;String address; to get returned object in this format. but getting proper format instead Entity error and that pojo is not error.
I want same type of concept as marshalling of json string to corresponding pojo.
Upvotes: 1
Views: 9512
Reputation: 3309
When you execute the query
Query q=em.createQuery("select t1.name,t2.address from T1 t1, T2 t2");
Collection c = q.getResultList();
you'll get a collection of zero or more instances of arrays of type Object. If you want the result of the query be mapped to a POJO, you can use the so called Construcot Expression
. To use it, first define your POJO as follows with an appropriate constructor:
package com.myproject.dto;
public class T1T2 {
private String name;
private String address;
public T1T2() {}
public T1T2(String name, String address) {
this.name = name;
this.address = address;
}
// getters + setters
}
Then you can formulate your query as follows:
String queryString = "SELECT NEW com.myproject.dto.T1T2(t1.name, t2.address) FROM T1 t1, T2 t2";
TypedQuery<T1T2> q = em.createQuery(queryString, T1T2.class);
Collection<T1T2> result = q.getResultList();
Now you should have a collection of zero or more POJO instances and you don't need to cast.
Here is an extract from the JPA 2.0 Spec if you want to understand the details:
4.8.2 Constructor Expressions in the SELECT Clause
A constructor may be used in the SELECT list to return an instance of a Java class. The specified class is not required to be an entity or to be mapped to the database. The constructor name must be fully qualified.
If an entity class name is specified as the constructor name in the SELECT NEW clause, the resulting entity instances are in the new state.
If a single_valued_path_expression or identification_variable that is an argument to the constructor references an entity, the resulting entity instance referenced by that single_valued_path_expression or identification_variable will be in the managed state.
Note: Your query is building a x-product, do you really want that? As of now, you'll get any name with any address.
Upvotes: 0
Reputation: 608
If you want to use JPA for mapping to POJO's use @SqlResultSetMapping
annotation
Assuming T1T2
has a constructor T1T2(String name, String address)
add this to any of your entity class definition
@SqlResultSetMapping(name = "CUSTOM_MAPPING", classes = @ConstructorResult(
targetClass = T1T2.class,
columns = {@ColumnResult(name = "name", type = String.class),
@ColumnResult(name = "address", type = String.class)}))
Now you can use this mapping:
Query q=em.createNativeQuery("select t1.name,t2.address from T1 t1, T2 t2","CUSTOM_MAPPING");
List<T1T2> = q.getResultList();
Note that it work only on native queries. I'm assuming that there is no association defined at JPA entity level between T1 and T2, otherwise whole process is obsolete. If there is an association, use @JoinTable
annotation to declare it and JPA will make sure to fetch association along with entity.
Upvotes: 3
Reputation: 21456
In case you don't need full ORM functionality (or do not know how to do it properly), you can accomplish your task with Spring's JdbcTemplate
:
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List<T1T2> pojos = jdbcTemplate.query(
"SELECT t1.name, t2.address FROM T1 t1 JOIN T2 t2 ON t1.id=t2.id",
new BeanPropertyRowMapper(T1T2.class));
BeanPropertyRowMapper
maps result set columns to POJO fields that have the same name, respecting field types.
Upvotes: 0