I got the following entity:
#Entity
#Immutable
#Subselect("select distinct r.code, r.dsc\r\n"
+ "from roles r, accesses a\r\n"
+ "where r.code = '12'\r\n")
#MasterEntity(labelCode = "Scenario")
public class Scenario implements java.io.Serializable {
I want to use a dynamic query (or parameterized) instead of this static query.
for example: r.code should be equal to a parameter variable not "12"
is there a replacement for #Subselect while I use #Immutable?
I have the following entity class:
public class SportData {
//other attributes
#Column(name = "POINTS")
#ElementCollection
private Map<NBAEvent, Integer> points;
}
public enum NBAEvent {
THREE_POINT,
TWO_POINT,
FREE_THROW,
//..
}
When I generate the corresponding tables using ddl-auto: validate it creates the NBAEvent(which is the k) column with the data type as an integer(points_key int4 NOT NULL).
How can I generate a varchar type column for the points key column?
If I manually write the SQL like points_key CHARACTER VARYING(255) how would it affect?
I'm using Spring boot along with Spring JPA, DB is PostgreSQL.
When the key of your Map is an enum then you must also add the MapKeyEnumerated annotation.
The key is to declare it with the EnumType.STRING type.
#ElementCollection
#CollectionTable(name = "colltable")
#MapKeyEnumerated(EnumType.STRING)
#Column(name="POINTS")
private Map<NBAEvent, Integer> map;
Otherwise as per javadocs it defaults to: javax.persistence.EnumType.ORDINAL. And that results in an integer table while ddl creation.
you may also need the #CollectionTable annotation as above.
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.
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.
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.
Mapping JPQL Query Result to POJO
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.
I have the following relation of three classes:
#Entity
public class User{
#OnetoMany
List<Attribute> attributes = new ArrayList<Attribute>();
}
#Entity
public class Attribute{
#ManyToOne
AttributeType attributeType;
}
#Entity
public class AttributeType{
#Column
String type;
}
One user can have n attributes of m types.
I need to create HQL query which will return all Atribute Types List<AttributeType> of specific user attributes.
For example user has attribute a of type t, atribute b of type t and attribute c of type t1.
I need to return List<AttributeType> which will contain t and t1.
Please help. I just got lost in this query.
You shall map Attribute to User many to one relation, so the following query is what you need:
select distinct atr.attributeType
from Attribute atr
where atr.user = :user
I think the following query will work too:
select distinct atrs.attributeType
from User as user
join user.attributes as atrs
where user.id = :user_id
using a CRUD and want o access a certain value in the databse. what I tried is:
Query query = em.createNativeQuery("select o from Table o where o.IDfield= '938'");
Table o = (Table)query.getSingleResult();
but this fails.
Any suggestions?
Your select looks like a jpql query so it won't work when passed directly to the database as a native query. You can use the createQuery method instead. Even better would be to use a named parameterized query declared on your entity like this:
#Entity
#NamedQueries({#NamedQuery(name="MyEntity.findById", query="select o from MyEntity o where o.IDfield = :id"})
public class MyEntity {
#Id
private String IDfield;
}
...
MyEntity entity = (MyEntity)em.createNamedQuery("MyEntity.findById").setParameter("id", "938").getSingleResult();