org.hibernate.QueryException: could not resolve property: is_approved of: com - java

I am fetching records from purchase table by userid it was working fine but now want to add one condition that is (is_approved) column value is = 1,i added this condition in that same query it was throughing error
//My DAOHibernate method is below
public int getNumOfPurchasesByUserId(Integer userId) {
System.out.println("########################### Calling getNumOfPurchasesByUserId %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
String sql = "select count(p) from " + Purchase.class.getName() + " p where p.userid = :userid and p.is_approved=1";
Session session = null;
Query q = null;
int count = 0;
try {
session = getHibernateTemplate().getSessionFactory().openSession();
q = session.createQuery(sql);
q.setInteger("userid", userId);
try {
count = ((Long)q.uniqueResult()).intValue();
} catch (Exception e) {}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (session != null) {
session.close();
}
}
return count;
}
//my error is
########################### Calling getNumOfPurchasesByUserId %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
org.hibernate.QueryException: could not resolve property: is_approved of: com.newscom.model.Purchase [select count(p) from com.newscom.model.Purchase p where p.userid = :userid and p.is_approved=1]
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:81)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:75)
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1465)
at org.hibernate.hql.ast.tree.FromElementType.getPropertyType(FromElementType.java:315)
at org.hibernate.hql.ast.tree.FromElement.getPropertyType(FromElement.java:487)
at org.hibernate.hql.ast.tree.DotNode.getDataType(DotNode.java:611)
at org.hibernate.hql.ast.tree.DotNode.prepareLhs(DotNode.java:263)
at org.hibernate.hql.ast.tree.DotNode.resolve(DotNode.java:210)
at org.hibernate.hql.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:117)
at org.hibernate.hql.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:113)
at org.hibernate.hql.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:880)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1330)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4471)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:3944)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2047)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1975)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:831)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:617)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:244)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:256)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:138)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1770)
at com.newscom.dao.hibernate.PurchaseDAOHibernate.getNumOfPurchasesByUserId(PurchaseDA
//In purchase
#Entity
#Table(name = "Purchase")
#NamedQueries(value = {
#NamedQuery(name = "GetPurchaseByUserID", query = "SELECT p from Purchase p where p.userid = :userid order by p.status, p.purchaseid desc"),
private boolean isApproved;
private Date approvalTime;
private Integer approvedBy;
#Column(name="is_approved")
public boolean getIsApproved() {
return isApproved;
}
public void setIsApproved(boolean isApproved) {
this.isApproved = isApproved;
}

You should use property name, not column name in your query:
String sql = "select count(p) from " + Purchase.class.getName() + " p where p.userid = :userid and p.isApproved=1";
Hope it helps.

Related

Hibernate query exception expecting d found f

I got this exception,
org.hibernate.QueryException: expecting 'd', found 'f' [from
com.carre.model.ProductOrder where sessieid =
4f5bf46709a6886e764207a00ec0]
code form controller:
Cookie[] cookies = request.getCookies();
String sessieid = cookies[0].getValue();
model.addAttribute("listProductorderNieuw", this.productorderService.listProductorderNieuw(sessieid));
code form DAO:
#SuppressWarnings("unchecked")
#Override
public List<ProductOrder> listProductorderNieuw(String id) {
Session session = this.sessionFactory.getCurrentSession();
List<ProductOrder> productList = session.createQuery("from ProductOrder where sessieid = " + id).list();
for (ProductOrder p : productList) {
logger.info("ProductOrder List::" + p);
}
return productList;
}
I have no idea where this exception is coming from.
Someone can help?
Can you try using named paramner as follows
Query query = session.createQuery("from ProductOrder where sessieid = :id ");
query.setParameter("id", id);
List<ProductOrder> productList = query.list();

Hibernate: getting data from two linked tables using Ctriteria API

How can I get data from two linked tables (one-to-many: one User and many Results) by value 'ispassed' (boolean) using Ctriteria API?
private List<?> winners;
try {
SessionFactory factory = HibernateUtil.getSessionFactory();
Session hSession = factory.openSession();
Transaction tx = null;
try {
tx = hSession.beginTransaction();
winners = hSession.createSQLQuery("select * from usertable u, resulttable r where u.id = r.id where r.ispassed = true").list();
tx.commit();
} catch (Exception e) {
if (tx != null)
tx.rollback();
} finally {
hSession.close();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(winners.size()); // an exception
You can use HQL:
from usertable u, resulttable r where u.id = r.id
where r.ispassed = 1
This will return a list of [User,result] arrays.
Change you code like:
private List<?> winners;
try {
SessionFactory factory = HibernateUtil.getSessionFactory();
Session hSession = factory.openSession();
Transaction tx = null;
try {
tx = hSession.beginTransaction();
winners = hSession.createSQLQuery("from usertable u, resulttable r where u.id = r.id and r.ispassed = true").list();
tx.commit();
} catch (Exception e) {
if (tx != null)
tx.rollback();
} finally {
hSession.close();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(winners.size());
EDIT:
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<Tuple> c = b.createTupleQuery();
Root<EntityX> entityXRoot= c.from(EntityX.class);
Root<EntityY> entityYRoot = c.from(EntityY.class);
List<Predicate> predicates = new ArrayList<>();
//Here you need to add the predicates you need
List<Predicate> andPredicates = new ArrayList<>();
andPredicates.add(b.equal(entityXRoot.get("id"), entityYRoot.get("id")));
andPredicates.add(b.and(predicates.toArray(new Predicate[0])));
c.multiselect(entityXRoot, entityYRoot);
c.where(andPredicates.toArray(new Predicate[0]));
TypedQuery<Tuple> q = em.createQuery(criteria);
List<Tuple> result = q.getResultList();
You can create your entity class like below
#Entity
#Table(name="RESULTS")
public class Results implements Serializable {
#Id
#GeneratedValue()
#Column(name="ID")
private Long id;
#ManyToOne
#JoinColumn(name="USER_ID")
private User userId;
#Column(name = "IS_PASSED")
private Boolean ispassed;
other property
... getter() setter()
}
#Entity
#Table(name="USER")
public class User implements Serializable {
#Id
#GeneratedValue()
#Column(name="ID")
private Long id;
#OneToMany(mappedBy = "userId",cascade=CascadeType.ALL)
private Set<Results> resultsSet;
other property
... getter() setter()
}
And in your hibernate.cfg.xml file if set below property
<property name="hibernate.query.substitutions">true 1, false 0</property>
Execute below HQL query
String sql = "from User as user "
+ "inner join user.resultsSet"
+ "where resultsSet.ispassed= true";
Query query = getCurrentSession().createQuery(sql);
List<User> UserList = query.list();
above is how you can get List of User, now you need to Iterate User list and use getter method get all results.

"operator does not exist: uuid = bytea" Java with Postgres

I have a problem referring to this query. On Postgres, this query executes without errors. On JAVA, it throws the following exception:
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
cause
org.postgresql.util.PSQLException: ERROR: operator does not exist: uuid = bytea
Note: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Position: 404
What I do?
My Method:
public List<CivilRecord> dashboardSearch(CivilRecordSearch civilRecordSearch)
throws MessageException {
SearchValidation.validateDashboardSearch(civilRecordSearch);
List<CivilRecord> l = new ArrayList<>();
try {
StringBuilder query = new StringBuilder();
// query.append("select
// c.id_civil_record\\:\\:text,c.nm_request,c.nm_rg,c.tx_name,c.dt_register,c.bl_priority
// ");
query.append("select c.id_civil_record,c.nm_request,c.nm_rg,c.tx_name,c.dt_register,c.bl_priority ");
query.append("from sc_civil.tb_civil_record c ");
query.append("inner join sc_civil.tb_workflow_record w ");
query.append("on w.id_civil_record = c.id_civil_record ");
query.append("left join sc_civil.tb_lock l ");
query.append("on l.id_record = c.id_civil_record ");
query.append("where c.id_site = :idSite ");
if (civilRecordSearch.getPriority() == null || civilRecordSearch.getPriority().equals(false))
query.append("and c.bl_priority = :priority ");
query.append("and c.bl_canceled = :canceled ");
query.append("and w.id_type_workflow = :idTypeWorkflow ");
query.append("and w.id_type_status_workflow = :idTypeStatusWorkflow ");
query.append("and (l is null or l.id_user = :idUser) ");
if (!StringUtils.isEmpty(civilRecordSearch.getName()))
query.append("and c.tx_name ilike :name ");
if (!StringUtils.isEmpty(civilRecordSearch.getRg()))
query.append("and c.nm_rg like :rg ");
if (civilRecordSearch.getRequestNumber() != null)
query.append("and c.nm_request = :request ");
query.append("order by c.bl_priority desc, c.dt_register ");
Query q = em.createNativeQuery(query.toString());
q.setParameter("idSite", civilRecordSearch.getSite().getId());
if (civilRecordSearch.getPriority() == null || civilRecordSearch.getPriority().equals(false))
q.setParameter("priority", false);
q.setParameter("idTypeWorkflow", civilRecordSearch.getTypeworkflow().getId());
q.setParameter("idTypeStatusWorkflow", civilRecordSearch.getTypestatusworkflow().getId());
q.setParameter("idUser", civilRecordSearch.getIdUser());
q.setParameter("canceled", false);
if (!StringUtils.isEmpty(civilRecordSearch.getName()))
q.setParameter("name", "%" + civilRecordSearch.getName() + "%");
if (civilRecordSearch.getRequestNumber() != null)
q.setParameter("request", civilRecordSearch.getRequestNumber());
if (!StringUtils.isEmpty(civilRecordSearch.getRg()))
q.setParameter("rg", civilRecordSearch.getRg());
q.setMaxResults(maxResult);
List<Object []> lo = q.getResultList();
em.clear();
for (Object [] o : lo) {
CivilRecord c = new CivilRecord();
c.setIdCivilRecord(UUID.fromString((String) o[0]));
c.setRequest((Long) o[1]);
c.setRg((String) o[2]);
c.setName((String) o[3]);
c.setWorkflowRecords(findStatus(c.getIdCivilRecord()));
l.add(c);
}
return l;
}
catch (Exception e) {
log.severe(e.getMessage());
throw e;
}
}
My Class CivilRecordSearch:
import java.io.Serializable;
import java.util.UUID;
public class CivilRecordSearch implements Serializable {
private static final long serialVersionUID = 1701325902333490974L;
// site, prioridade, tipo wf e status wf
private Site site;
private Boolean priority;
private TypeWorkflow typeworkflow;
private TypeStatusWorkflow typestatusworkflow;
private Integer amount;
private UUID idUser;
private String name;
private String rg;
private Long requestNumber;
public Site getSite() {
return site;
}
public void setSite(Site site) {
this.site = site;
}
public Boolean getPriority() {
return priority;
}
public void setPriority(Boolean priority) {
this.priority = priority;
}
public TypeWorkflow getTypeworkflow() {
return typeworkflow;
}
public void setTypeworkflow(TypeWorkflow typeworkflow) {
this.typeworkflow = typeworkflow;
}
public TypeStatusWorkflow getTypestatusworkflow() {
return typestatusworkflow;
}
public void setTypeStatusWorkflow(TypeStatusWorkflow typestatusworkflow) {
this.typestatusworkflow = typestatusworkflow;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public UUID getIdUser() {
return idUser;
}
public void setIdUser(UUID idUser) {
this.idUser = idUser;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRg() {
return rg;
}
public void setRg(String rg) {
this.rg = rg;
}
public Long getRequestNumber() {
return requestNumber;
}
public void setRequestNumber(Long requestNumber) {
this.requestNumber = requestNumber;
}
}
I solve my problem with this form:
I utilized the command CAST for my UUID fields
public List<CivilRecord> dashboardSearch(CivilRecordSearch civilRecordSearch)
throws MessageException {
SearchValidation.validateDashboardSearch(civilRecordSearch);
List<CivilRecord> l = new ArrayList<>();
try {
StringBuilder query = new StringBuilder();
//query.append("select c.id_civil_record\\:\\:text,c.nm_request,c.nm_rg,c.tx_name,c.dt_register,c.bl_priority ");
query.append("select CAST(c.id_civil_record as text),c.nm_request,c.nm_rg,c.tx_name,c.dt_register,c.bl_priority ");
query.append("from sc_civil.tb_civil_record c ");
query.append("inner join sc_civil.tb_workflow_record w ");
query.append("on w.id_civil_record = c.id_civil_record ");
query.append("left join sc_civil.tb_lock l ");
query.append("on l.id_record = c.id_civil_record ");
query.append("where c.id_site = :idSite ");
if (civilRecordSearch.getPriority() == null || civilRecordSearch.getPriority().equals(false))
query.append("and c.bl_priority = :priority ");
query.append("and c.bl_canceled = :canceled ");
query.append("and w.id_type_workflow = :idTypeWorkflow ");
query.append("and w.id_type_status_workflow = :idTypeStatusWorkflow ");
query.append("and (l is null or l.id_user = CAST(:idUser AS uuid)) ");
if (!StringUtils.isEmpty(civilRecordSearch.getName()))
query.append("and c.tx_name ilike :name ");
if (!StringUtils.isEmpty(civilRecordSearch.getRg()))
query.append("and c.nm_rg like :rg ");
if (civilRecordSearch.getRequestNumber() != null)
query.append("and c.nm_request = :request ");
query.append("order by c.bl_priority desc, c.dt_register ");
Query q = em.createNativeQuery(query.toString());
q.setParameter("idSite", civilRecordSearch.getSite().getId());
if (civilRecordSearch.getPriority() == null || civilRecordSearch.getPriority().equals(false))
q.setParameter("priority", false);
q.setParameter("idTypeWorkflow", civilRecordSearch.getTypeworkflow().getId());
q.setParameter("idTypeStatusWorkflow", civilRecordSearch.getTypestatusworkflow().getId());
q.setParameter("idUser", civilRecordSearch.getIdUser().toString());
q.setParameter("canceled", false);
if (!StringUtils.isEmpty(civilRecordSearch.getName()))
q.setParameter("name","%" + civilRecordSearch.getName() + "%");
if (civilRecordSearch.getRequestNumber() != null)
q.setParameter("request", civilRecordSearch.getRequestNumber());
if (!StringUtils.isEmpty(civilRecordSearch.getRg()))
q.setParameter("rg", civilRecordSearch.getRg());
q.setMaxResults(maxResult);
List<Object[]> lo = q.getResultList();
em.clear();
for(Object[] o : lo){
CivilRecord c = new CivilRecord();
c.setIdCivilRecord(UUID.fromString((String)o[0]));
c.setRequest(((BigInteger)o[1]).longValue());
c.setRg((String)o[2]);
c.setName((String)o[3]);
c.setRegister((Date)o[4]);
c.setPriority(TypeYesNo.getByKey(((Boolean)o[5]).booleanValue()));
c.setWorkflowRecords(findStatus(c.getIdCivilRecord()));
l.add(c);
}
return l;
} catch (Exception e) {
log.severe(e.getMessage());
throw e;
}
}
Problem:
Hibernate should map the java UUID type to the postgress uuid type. However, if hibernate does not know how to map this, it will just try to serialize the object, resulting in a byte[]. Of course, this just moves the issue to the database level. Values of the uuid postgress type cannot just be compared with byte array type.
PSQLException: ERROR: operator does not exist: uuid = bytea
Possible cause:
I encountered this issue when migrating from Spring Boot 1.x to Spring Boot 2.3.0. In Spring Boot 1.x it was sufficient for me to mark my id fields with #Id and to make them of java type UUID.
Quick and dirty solutions:
A possible solution, is to explicitly state the PSQL type for the id field.
#Type(type="org.hibernate.type.PostgresUUIDType")
#Id
private UUID id;
A better solution, would be to define a system-wide replacement. You could put this declaration on any class or on a package. Defining it just once somewhere impacts all declarations of UUID actually.
#TypeDef(name="postgres-uuid",
defaultForType = UUID.class,
typeClass = PostgresUUIDType.class)
Real solution:
Take a look in your log file, and you may see something like this. Double check the version of this dialect, and see if it matches with the one which you defined in your property files:
Dialect - HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL81Dialect
In that case, be aware that the following property is outdated:
hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
Some of the hibernate properties now need to have a spring.jpa.properties prefix. So, in this case, the new property path should be spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect.
Which is the point where everything starts to make sense. This dialect does all required type definitions for you.
The same error can be caused by accidentally passing null as an argument, which is then regarded as a bytea type, making the cast to uuid impossible.
So, before going into the solutions above, I would recommend checking one's business logic and quickly activating the hibernate binding parameters logs in application.yml:
logging:
level:
org:
hibernate:
type: TRACE
The faulty argument then becomes apparent, as in my case:
....
binding parameter [6] as [VARBINARY] - [null]
...
To also see the sql queries, add:
spring:
jpa:
show-sql: true
Similar response to Robson Silveira.
Pay attention to the last bit of the query string.
public Account getAccount(String name, String password, String tenantId) {
Query q = em.createNativeQuery(
"SELECT a.id, a.name, a.password, a.email FROM accounts a WHERE name = :name and password = :password and tenant_fk = CAST(:tenant_fk AS uuid)"
);
q.setParameter("name", name);
q.setParameter("password", password);
q.setParameter("tenant_fk", tenantId);
List<Object[]> results = q.getResultList();
if (results.size() == 0) {
return null;
}
return mapFromObject(results.get(0));
}

Hibernate SQL Query result Mapping/Convert TO Object/Class/Bean

1 2: select (table.*)/(all column) is OK
String sql = "select t_student.* from t_student";
//String sql = "select t_student.id,t_student.name,... from t_student"; //select all column
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Student.class);//or query.addEntity("alias", Student.class);
//query.list();[Student#..., Student#..., Student#...]
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); //or other transformer
query.list(); //[{Student(or alias)=Student#...},{Student=Student#...}]
3: select some column(not all of), is Error
String sql = "select t_student.id,t_student.name.t_student.sex from t_student";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Student.class);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
query.list(); //Exception:invalid column/no column
I want "3" to work ok, and let the result can be mapped to Student.class.
Like: Student[id=?, name=?, sex=?, (other field are null/default)]
I've no idea for this error, help me please!
You can go further and add
.setResultTransformer(Transformers.aliasToBean(YOUR_DTO.class));
and automatically map it to your custom dto object, see also Returning non-managed entities.
For example:
public List<MessageExtDto> getMessagesForProfile2(Long userProfileId) {
Query query = getSession().createSQLQuery(" "
+ " select a.*, b.* "
+ " from messageVO AS a "
+ " INNER JOIN ( SELECT max(id) AS id, count(*) AS count FROM messageVO GROUP BY messageConversation_id) as b ON a.id = b.id "
+ " where a.id > 0 "
+ " ")
.addScalar("id", new LongType())
.addScalar("message", new StringType())
......... your mappings
.setResultTransformer(Transformers.aliasToBean(MessageExtDto.class));
List<MessageExtDto> list = query.list();
return list;
}
I want "3" to work ok, and let the result can be mapped to Student.class
That's possible using
Query createNativeQuery(String sqlString, String resultSetMapping)
In the second argument you could tell the name of the result mapping. For example:
1) Let's consider a Student entity, the magic is going to be in the SqlResultSetMapping annotation:
import javax.persistence.Entity;
import javax.persistence.SqlResultSetMapping;
import javax.persistence.Table;
#Entity
#Table(name = "student")
#SqlResultSetMapping(name = "STUDENT_MAPPING", classes = {#ConstructorResult(
targetClass = Student.class, columns = {
#ColumnResult(name = "name"),
#ColumnResult(name = "address")
})})
public class Student implements Serializable {
private String name;
private String address;
/* Constructor for the result mapping; the key is the order of the args*/
public Student(String aName, String anAddress) {
this.name = aName;
this.address = anAddress;
}
// the rest of the entity
}
2) Now you can execute a query which results will be mapped by STUDENT_MAPPING logic:
String query = "SELECT s FROM student s";
String mapping = "STUDENT_MAPPING";
Query query = myEntityManager.createNativeQuery(query, mapping);
#SuppressWarnings("unchecked")
List<Student> students = query.getResultList();
for (Student s : students) {
s.getName(); // ...
}
Note: I think it's not possible to avoid the unchecked warning.
There is only two ways.
You can use 1st or 2nd snippet. According to Hibernate documentation you must prefer 2nd.
You can get just a list of object arrays, like this:
String sql = "select name, sex from t_student";
SQLQuery query = session.createSQLQuery(sql);
query.addScalar("name", StringType.INSTANCE);
query.addScalar("sex", StringType.INSTANCE);
query.list();
I had same problem on HQL Query. I solved the problem by changing the transformer.
The problem caused the code written to transform as Map. But it is not suitable for Alias Bean. You can see the error code at below. The code written to cast result as map and put new field to the map.
Class : org.hibernate.property.access.internal.PropertyAccessMapImpl.SetterImpl
m
Method: set
#Override
#SuppressWarnings("unchecked")
public void set(Object target, Object value, SessionFactoryImplementor factory) {
( (Map) target ).put( propertyName, value );
}
I solved the problem to duplicate the transformer and change the code.
You can see the code in the project.
Link : https://github.com/robeio/robe/blob/DW1.0-migration/robe-hibernate/src/main/java/io/robe/hibernate/criteria/impl/hql/AliasToBeanResultTransformer.java
Class:
import java.lang.reflect.Field;
import java.util.Map;
import io.robe.hibernate.criteria.api.query.SearchQuery;
import org.hibernate.HibernateException;
import org.hibernate.transform.AliasedTupleSubsetResultTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AliasToBeanResultTransformer extends AliasedTupleSubsetResultTransformer {
private static final Logger LOGGER = LoggerFactory.getLogger(AliasToBeanResultTransformer.class);
private final Class resultClass;
// Holds fields of Transform Class as Map. Key is name of field.
private Map<String, Field> fieldMap;
public AliasToBeanResultTransformer(Class resultClass) {
if ( resultClass == null ) {
throw new IllegalArgumentException( "resultClass cannot be null" );
}
fieldMap = SearchQuery.CacheFields.getCachedFields(resultClass);
this.resultClass = resultClass;
}
#Override
public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) {
return false;
}
#Override
public Object transformTuple(Object[] tuple, String[] aliases) {
Object result;
try {
result = resultClass.newInstance();
for ( int i = 0; i < aliases.length; i++ ) {
String name = aliases[i];
Field field = fieldMap.get(name);
if(field == null) {
LOGGER.error(name + " field not found in " + resultClass.getName() + " class ! ");
continue;
}
field.set(result, tuple[i]);
}
}
catch ( InstantiationException e ) {
throw new HibernateException( "Could not instantiate resultclass: " + resultClass.getName() );
} catch ( IllegalAccessException e ) {
throw new HibernateException( "Could not instantiate resultclass: " + resultClass.getName() );
}
return result;
}
}
After created new Transformer You can use like below.
query.setResultTransformer(new AliasToBeanResultTransformer(YOUR_DTO.class));
You can mapped it automatically:
Your Model Student.java
public class Student {
private String name;
private String address;
}
Repository
String sql = "Select * from student";
Query query = em.createNativeQuery(sql, Student.class);
List ls = query.getResultList();
so it will automatically mapped the result with the Student class

select query in java (JPA)

I'm selecting records in JAVA with JPA and playframework like this:
EntityManager em = JPA.em();
List<News> resultUrl = News.find("link", url).fetch();
if (resultUrl.isEmpty()) { //check if it is exist
}
But i want to select records with two condition, like this:
where link='url' and name='joe'
How can i do this?
Thanks for helping.
Best wishes.
Use:
Query q = em.createQuery("FROM News n WHERE n.link=:url and n.name=:name");
q.setParameter("url", "url").setParameter("name", "joe");
List<News> resultUrl = q.getResultList();
...
One way to do it with Play is
List<News> resultUrl = News.find("byLinkAndName", url, "joe").fetch();
if (resultUrl.isEmpty()) { //check if it is exist
}
Another:
List<News> resultUrl = News.find("link = ? and name = ?", url, "joe").fetch();
if (resultUrl.isEmpty()) { //check if it is exist
}
My proposal is to define a named query:
#Entity
#NamedQueries({
#NamedQuery(name = News.FIND_BY_URL_AND_NAME, query = "Select n FROM News as n WHERE n.url=:" + News.PARAM_URL + " AND n.name=:" + News.PARAM_NAME)
})
public class News {
public static final String FIND_BY_URL_AND_NAME = "News.findByUrlAndName";
public static final String PARAM_URL = "url";
public static final String PARAM_NAME = "name";
//CONTINUE
}
Then you call it like that:
Query query = em.createNamedQuery(News.FIND_BY_URL_AND_NAME);
query.setParameter(News.PARAM_URL, "url");
query.setParameter(News.PARAM_NAME, "name");
List<News> news = query.getResultList();
Get a look at CriteriaBuilder, CriteriaQuery and Predicate :
EntityManager em = JPA.em();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = cb.createQuery(News.class);
Root<T> root = criteriaQuery.from(News.class);
criteriaQuery.select(root);
List<Predicate> ps = new ArrayList<Predicate>();
ps.add(sb.equal(root.get("link", url));
ps.add(sb.equal(root.get("name", "joe"));
criteriaQuery.where(cb.and(ps.toArray(new Predicate[0])));
List<News> resultUrl = em.createQuery(criteriaQuery).getResultList();
Regards

Categories