search on Long value in Database with CriteriaBuilder - java

im trying to search for an "Order" in my "Order"-table in my database, and i'm not finding it because of the get() method, which accepts just strings and not long values.
Here is the code:
public List<OrderItemEntity> findOrderItem(OrderItem orderitem){
long id = orderitem.getId();
EntityManager em = emf.createEntityManager();
try {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<OrderItemEntity> cq = cb.createQuery(OrderItemEntity.class);
Root<OrderItemEntity> root = cq.from(OrderItemEntity.class);
cq.where(cb.equal(root.get("id"), String.valueOf(id))); <<---- THIS LINE!!
TypedQuery query = em.createQuery(cq);
List<OrderItemEntity> result = query.getResultList();
System.out.println("orderID found is: " + result.get(0).getId());
return result;
} finally {
em.close();
}
}
can anyone help? How could I cast that "id" in a string value?
Thanks!

If id is your primary id it would be easier to just find your entity with:
OrderItemEntity myitem = em.find(OrderItemEntity.class, id);
Alternatively, use select method in your query and everything should work fine (String.valueof should you are using is OK):
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<OrderItemEntity> cq = cb.createQuery(OrderItemEntity.class);
Root<OrderItemEntity> root = cq.from(OrderItemEntity.class);
cq.select( root );
cq.where(cb.equal(root.get("id"), String.valueOf(id)));
TypedQuery query = em.createQuery(cq);
List<OrderItemEntity> result = query.getResultList()

Related

Crieria Builder setMaxResults sort issue

I have written a query in Criteria Builder, its looks like this.
private EntityManager entitymanager;
CriteriaBuilder criteriaBuilder = entitymanager.getCriteriaBuilder();
CriteriaQuery<Object> criteriaQuery =
criteriaBuilder.createQuery(Object.class);
Root<Employee> from = criteriaQuery.from(Employee.class);
criteriaQuery.orderBy(criteriaBuilder.asc(name));
TypedQuery<Object> typedQuery1 = entitymanager.createQuery(criteriaQuery );
List<Object> resultlist1 = typedQuery1.getResultList();
typedQuery1.setMaxResults(pageable.getPageSize());
After setMaxResults apply to the query, the order of the resultlist1 is
different as before?
Why is this happened?
How can I stop this behavior?
Why are you using Object for type? Use Employee
CriteriaQuery<Employee> criteriaQuery =
criteriaBuilder.createQuery(Employee.class);
Root<Employee> from = criteriaQuery.from(Employee.class);
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("column_name")));
TypedQuery<Employee> typedQuery1 = entitymanager.createQuery(criteriaQuery);
typedQuery1.setMaxResults(pageable.getPageSize());
List<Employee> resultlist1 = typedQuery1.getResultList();
Calling setMaxResults() after executing query does not make sense. Set max result before calling getResultList()
typedQuery1.setMaxResults(pageable.getPageSize());
List<Employee> resultlist1 = typedQuery1.getResultList();
What is name variable? Do order by like this:
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("column_name")));

How to convert List<Long> to Expression<Long> int Java? [duplicate]

How to write criteria builder api query for below given JPQL query?
I am using JPA 2.2.
SELECT *
FROM Employee e
WHERE e.Parent IN ('John','Raj')
ORDER BY e.Parent
This criteria set-up should do the trick:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> q = cb.createQuery(Employee.class);
Root<Employee> root = q.from(Employee.class);
q.select(root);
List<String> parentList = Arrays.asList(new String[]{"John", "Raj"});
Expression<String> parentExpression = root.get(Employee_.Parent);
Predicate parentPredicate = parentExpression.in(parentList);
q.where(parentPredicate);
q.orderBy(cb.asc(root.get(Employee_.Parent));
q.getResultList();
I have used the overloaded CriteriaQuery.where method here which accepts a Predicate.. an in predicate in this case.
You can also do this with Criteria API In clause as below:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
Root<Employee> root = cq.from(Employee.class);
List<String> parentList = Arrays.asList("John", "Raj");
In<String> in = cb.in(root.get(Employee_parent));
parentList.forEach(p -> in.value(p));
return entityManager
.createQuery(cq.select(root)
.where(in).orderBy(cb.asc(root.get(Employee_.Parent)))
.getResultList();
Checkout my Github for this and almost all possible criteria examples.
List<String> parentList = Arrays.asList("John", "Raj");
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Employee> query = cb.createQuery(Employee.class);
final Root<Employee> employee = query.from(Employee.class);
query.select(employee).where(employee.get("Parent").in(parentList));
this should work fine. for more info please refer this article by baeldung. it is very resourceful https://www.baeldung.com/jpa-criteria-api-in-expressions
I hope it could be useful. The code tested in case when Entry has only one #Id column:
public static <Entry, Id> List<Entry> getByIds(List<Id> ids, Class<Entry> clazz, EntityManager entityManager) throws CustomDatabaseException
{
List<Entry> entries;
try
{
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Entry> q = cb.createQuery(clazz);
Root<Entry> root = q.from(clazz);
EntityType<Entry> e = root.getModel();
CriteriaQuery<Entry> all = q.where(root.get(e.getId(e.getIdType().getJavaType()).getName()).in(ids));
TypedQuery<Entry> allQuery = entityManager.createQuery(all);
entries = allQuery.getResultList();
}
catch (NoResultException nre)
{
entries = Collections.emptyList()
}
catch (Exception e)
{
throw new CustomDatabaseException(e);
}
return entries;
}
Not to break your head when you need to do this again using Criteria API - you can create a parent wrapper class for your Dao and put a hepler method there:
/**
* An SQL "WHERE IN" expression alternative.
*
* #param inList List to search in.
* #param pathToEntityField Path to a field in your entity object.
* #return A ready predicate-condition to paste into CriteriaQuery.where().
*/
#SuppressWarnings("unchecked")
private Predicate in(List<?> inList, Expression pathToEntityField) {
return pathToEntityField.in(inList);
}
Use WHERE IN then like:
query.where(**in**(myList, root.get(MyTypedEntity_.id)));

JPA Critera Query count results involving join

I'm using hibernate and the JPA criteria API and trying to create a re-usable utility method to determine how many rows a query will return.
Currently I have this:
Long countResults(CriteriaQuery cq, String alias){
CriteriaBuilder cb = em().getCriteriaBuilder();
CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
Root ent = countQuery.from(cq.getResultType());
ent.alias(alias);
countQuery.select(cb.count(ent));
Predicate restriction = cq.getRestriction();
if(restriction != null){
countQuery.where(restriction);
}
return em().createQuery(countQuery).getSingleResult();
}
Which I use like this:
CriteriaBuilder cb = em().getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(modelClass());
root.alias("ct");
cq.select(root);
TypedQuery<User> query = em().createQuery(cq);
long count = countResults(cq, "ct");
And that works fine.
However, when I use a more complicated query like
Join<UserThing, Thing> j = root.join(User_.things).join(UserThing_.thing);
cq.where(somePredicate);
My call to countResults() produces exceptions like org.hibernate.hql.internal.ast.InvalidPathException: Invalid path: 'myAlias.name', <AST>:0:0: unexpected end of subtree, left-hand operand of a binary operator was null
I'm guessing this has something to do with the join, and that I need to alias that somehow, but I've not had any success so far.
Help?
I had the same problem, and I solved with:
CriteriaQuery<Long> countCriteria = cb.createQuery(Long.class);
Root<EntityA> countRoot = countCriteria.from(cq.getResultType());
Set<Join<EntityA, ?>> joins = originalEntityRoot.getJoins();
for (Join<EntityA, ?> join : joins) {
countRoot.join(join.getAttribute().getName());
}
countCriteria.select(cb.count(countRoot));
if(finalPredicate != null)
countCriteria.where(finalPredicate);
TypedQuery<Long> queryCount = entityManager.createQuery(countCriteria);
Long count = queryCount.getSingleResult();
Where
originalEntityRoot is the main root where I did the query with the where clauses.

How to join 2 tables based on passing a parameter for search operation?

I have 2 entities Addemp and Job.I want to join these 2 tables based on empid .empid is foreign key in job table and primary key in addemp table
here i am doing a search operation based on employee id .i am using criteria builder for search operation
the relationship here is manytoone
public List<Object[]> findEmployeeList(Integer id)
{
EntityManager em=null;
try
{
em=getEntityManager();
CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(Addemp.class);
Root<Addemp>rt= cq.from(Addemp.class);
Join<Addemp,Job> job=rt.join(Addemp_.jobCollection);
Predicate predicate=cb.equal(rt.get("empId"),id);
cq.where(predicate);
/* cq.select(rt.get("firstName"));
cq.where (cb.equal(rt.<String>get("empId"),id));*/
Query qry= em.createQuery(cq);
return qry.getResultList();
Based on the question and JPQL query from the above comments here is the criteria query proposal:
public List<Tuple> findEmployeeList(Integer id)
{
em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<Addemp> empRoot = cq.from(Addemp.class);
Root<Job> jobRoot = cq.from(Job.class);
cq.multiselect(empRoot.get("empId").alias("id"),
empRoot.get("firstName").alias("first"),
empRoot.get("lastName").alias("last"),
jobRoot.get("jobTitle").alias("title"),
jobRoot.get("empStatus").alias("status"),
jobRoot.get("subUnit").alias("subunit"));
cq.where(cb.equal(empRoot.get("empId"), id));
TypedQuery<Tuple> q = em.createQuery(cq);
return q.getResultList();
}
Next you may want to extract a tuple result:
List<Tuple> tuples = service.findEmployeeList(2);
for (Tuple t : tuples) {
StringBuilder builder = new StringBuilder(64)
.append(t.get("id")).append(", ")
.append(t.get("first")).append(", ")
.append(t.get("last")).append(", ")
.append(t.get("title")).append(", ")
.append(t.get("status")).append(", ")
.append(t.get("subunit"));
System.out.println(builder.toString());
}
I hope it helps.

Equivalent criteria query for named query

My named query looks like this, thanks to here.
#NamedQuery(
name="Cat.favourites",
query="select c
from Usercat as uc
inner join uc.cat as c
where uc.isFavourtie = true
and uc.user = :user")
And the call to implement looks like this :
Session session = sessionFactory.getCurrentSession();
Query query = session.getNamedQuery("Cat.favourites");
query.setEntity("user", myCurrentUser);
return query.list();
What would be the equivalent criteria query that returns a list of cats ?
With JPA 2.0 Criteria:
(This is one of the many ways you can achieve this using JPA 2.0 Criteria api)
final CriteriaQuery<Cat> cq = getCriteriaBuilder().createQuery(Cat.class);
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final Root<Usercat> uc= cq.from(Usercat.class);
cq.select(uc.get("cat");
Predicate p = cb.equal(uc.get("favourtie", true);
p = cb.and(p, cb.equal(uc.get("user"), user));
cq.where(p);
final TypedQuery<Cat> typedQuery = entityManager.createQuery(cq);
return typedQuery.getResultList();

Categories