Hibernate Restriction to search with like clause in list - java

I need help with hibernate criteria restriction.
As we know that we use IN restriction with list , i.e
Criteria criteria = session.createCriteria(Student.class);
List<String> studentNames= new ArrayList();
criteria.add(Restrictions.in("name",studentNames);
List list = criteria.list();
and to use like
we use restriction like this i.e
String matchString = "Suraj Kumar";
criteria.add(Restrictions.like(
"studentName", matchString));
Problem: What i want is that every element in list should be searched with "LIKE" clause. If we use IN clause, then it compares the element with all the elements passed in the IN clause, and that comparison is based on equality.
But requirement is that , every element in the list should be checked with the LIKE clause , with the corresponding database column.
Please help me to create hibernate criteria restriction with the same.
Thanks

You can try to use Disjunction which can be used if you have multiple OR conditions.
Criteria criteria = session.createCriteria(Student.class);
List<String> studentNames= new ArrayList();
Disjunction disj = Restrictions.disjunction();
for (String value : studentNames) {
disj.add(Restrictions.like("name", value));
}
criteria.add(disj);
List list = criteria.list();

Related

Hibernate projection property whole object

I have a case like this:
Class Foo with two children (A and B), each being Objects.
In Hibernate, if I want to return only a list of the children, I would use projections on my criteria:
criteria.setProjection(Projections.property("A"));
This gives me a list of A objects, but they are all lazy loaded. As soon as I try to access anything other than the id, obviously things go wrong.
My SQL query indeed shows it:
select A from Foo ...
Logically, only my id is filled in, and not the rest of my properties. How do I solve this problem so I get a list of A objects that have everything filled in?
I tried this:
criteria.setResultTransformer(Transformers.aliasToBean(A.class));
but without success.
if you use hql it would be more efficient:
String hql = "SELECT f.A FROM Foo f";
Query query = session.createQuery(hql);
List results = query.list();
Using criteria I would have use this code
Criteria crit = session.createCriteria(Foo.class);
ProjectionList proList = Projections.projectionList();
proList.add(Projections.property("A"));
crit.setProjection(proList);
List As= crit.list();
or this block
Criteria crit = session.createCriteria(Foo.class);
crit.createAlias("A","a").setProjection(Projections.property("a"));
List As= crit.list();

Return single column from multi-group Hibernate projection

What I want to achieve:
Select a susbset of entities that have a property value that exists in a List of values. This list is returned by another Query.
In plain SQL, this can be easily achieved with subqueries. This is the Criteria query that returns the relevant values:
DetachedCriteria subq = DetachedCriteria.forClass(MyClass.class)
.setProjection(
Projections.projectionList()
.add(Projections.alias(Projections.max("interestingVal"), "interestingVal"))
.add(Projections.groupProperty("someval1"))
.add(Projections.groupProperty("someval2"))
.add(Projections.groupProperty("someval3"))
);
I would then like to select the entities that have a value of interesting_val that was returned by the above query. Like so:
List<MyClass> resultList = sessionFactory.getCurrentSession().createCriteria(MyClass.class)
.add(Subqueries.propertyIn("interestingVal", subq))
.list();
Unfortunately, the subq subquery returns a List of Object-arrays with length 4, since I have 4 Projection values. All projection values seem to be automatically added to the SELECT clause. This results in an
SQLSyntaxErrorException: ORA-00913: too many values.
How can I either tell my second Criteria query to only use the first element in the Object array or only retrieve the first column in my subquery?
Instead of propertyIn try propertiesIn.
String[] vals = new String[]{"interestingVal", "someval1", "someval2", "someval3"};
List<MyClass> resultList = sessionFactory.getCurrentSession().createCriteria(MyClass.class)
.add(Subqueries.propertiesIn(vals, subq))
.list();

How to retrieve all entity with different column value?

In the following criteria query
Criteria criteria = createLogRecordCriteria(maxId, playerId, playerStatus, userCategory, from, to);
criteria.setFirstResult(offset);
criteria.setMaxResults(limit);
criteria.setProjection(Projections.distinct(Projections.property("player")));
List lst = criteria.list();
return lst;
I retrieve only the set of different players , but I need to retireve all entities with different player value. How can it be done through criteria?
Believe this is the query that you are searching for.
For the below query:
select t from Table t
where t.player IN (select distinct t.player
from Table t
);
if DetachedCriteria is a feasible option, the subCriteria can be passed to the mainCriteria written as below (provided that subCriteria should be defined as a DetachedCriteria):
Criteria subCriteria = Criteria.forClass(Table.class);
subCriteria.setProjection(Projections.distinct(Projections.property("player")));
Criteria mainCriteria = createLogRecordCriteria(maxId, playerId, playerStatus, userCategory, from, to);
mainCriteria.add(Property.forName("t.player").in(subCriteria));
//adding the extra restrictions provided in the Question.
mainCriteria.setFirstResult(offset);
mainCriteria.setMaxResults(limit);
List lst = mainCriteria.list();
return lst;
If not, you have to get the result of 'sub-criteria' and then pass the same (in the form of Object[] or Collection) as the parameter to
> mainCriteria.add(Property.forName("t.player").in(Result_Of_subQuery));
Hope this helps.

get all the values in where clause for empty stirng using hibernate

i am building a shopping cart using jsp and hibernate.
i am filtering the content by brand size and price using checkboxes
the checked checkboxes are returned to the class where hql query exists.
so i want i single hql query that can handle this.
as like if one of the parameter like size is empty (means user doesnt uses it to filter the content ) than an empty string is passed to the hql query which returns any value...
so is there anything possible that all values can be retrived in where clause for empty string or some other alternative except coding different methods for different parameter...
I typically use the Criteria api for things like this... if the user does not specify a size, do not add it to the criteria query.
Criteria criteria = session.createCriteria(MyClass.class);
if(size != null && !size.isEmpty()){
criteria.add(Restrictions.eq("size", size);
}
To have multiple restrictions via an OR statement, you use Disjunction. For an AND, you use Conjunction.
Criteria criteria = session.createCriteria(MyClass.class);
Disjunction sizeDisjunction = Restrictions.disjunction();
String[] sizes = { "small", "medium", "large" };
for(int i = 0; i < sizes.length; i++){
sizeDisjunction.add(Restrictions.eq("size", sizes[i]);
}
criteria.add(sizeDisjunction );
First, good practices say that instead of passing and empty String to the query, you should pass null instead. That said, this hql should help you:
from Product p
where p.brand = coalesce(:brand, p.brand)
and p.size = coalesce(:size, p.size)
and p.price = coalesce (:price, p.price)

JPA query.getResultList()?

I use JPA 1.0:
Query query;
query = em.createNamedQuery("getThresholdParameters");
query.setParameter(1, Integer.parseInt(circleId));
List<Object[]> resultList = new ArrayList();
resultList = query.getResultList();
Here I get result as List<Object[]>, thus I have to type convert all the parameters of the row to their respective types which is cumbersome.
In JPA 2.0 there is TypedQuery which return an entity object of type one specifies.
But as I am using JPA 1 I can't use it.
How to get result as Entity object of type I want??
EDIT:
QUERY
#Entity
#Table(name="GMA_THRESHOLD_PARAMETERS")
#NamedQuery(
name = "getThresholdParameters",
query = "select gmaTh.minNumberOc, gmaTh.minDurationOc, gmaTh.maxNumberIc, gmaTh.maxDurationIc, gmaTh.maxNumberCellId,"
+ "gmaTh.distinctBnumberRatio, gmaTh.minPercentDistinctBnumber from GmaThresholdParameter gmaTh "
+ "where gmaTh.id.circleId=?1 AND gmaTh.id.tspId=?2 AND gmaTh.id.flag=?3 "
)
Your query selects many fields. Such a query always returns a list of Object arrays. If you want a list containing instances of your GmaThresholdParameter entity, then the query should be
select gmaTh from GmaThresholdParameter gmaTh
where gmaTh.id.circleId=?1 AND gmaTh.id.tspId=?2 AND gmaTh.id.flag=?3
The code to get the list of entities would then be
List<GmaThresholdParameter> resultList = query.getResultList();
You'll get a type safety warning from the compiler, that you can ignore.
I can't respond to this as a comment so I'll just go ahead and make it an answer.
List<Object[]> resultList = new ArrayList(); // CREATE an empty ArrayList object
resultList = query.getResultList(); // getResultList ALSO returns its own ArrayList object
And since you assign the list that getResultList() returns to the same variable as you used for your own empty ArrayList, your application loses any connection to your own empty ArrayList and Java will collect it as garbage. Essentially you created it for absolutely no purpose.
what JB Nizet posted is enough.
List<GmaThresholdParameter> resultList = query.getResultList();
I have done something similar since I was using JPA 1 at that time:
final Collection<YourType> typedResult = new ArrayList<YourType>
for(final Object result : query.getResultList())
{
typedResult.add((YourType) result);
}
return typedResult;
List<GmaThresholdParamerter> result= query.getResultList();
for( GmaThresholdParamerter res : result)
{
System.out.println("" +res.getMinNumberOc());
System.out.println("" +res.getMinDurationOc());
}

Categories