How to retrieve all entity with different column value? - java

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.

Related

Hibernate Restriction to search with like clause in list

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();

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();

Hibernate select lowest value greater than

I am trying to get hibernate to return an object that has the lowest ID number that is greater than a certain value.
The code I have is returning an integer though, instead of the object.
Code
Criteria criteria = session.createCriteria(Story.class);
Criterion storyId = Restrictions.ge("id", 2);
ProjectionList projList = Projections.projectionList();
projList.add(Projections.min("id"));
criteria.add(storyId);
criteria.setProjection(projList);
List<?> storyResult = criteria.list();
session.close();
Story story = (Story) storyResult.get(0);
Right now this is returning "3" as an integer. 3 is the next available ID, but why is hibernate giving me back an integer instead of the object?
Thanks
By adding a Projection, you are essentially asking Hibernate to change your query from SELECT * FROM TABLE to a SELECT MIN(ID) FROM TABLE query. That's one of the features of a projection.
To achieve what you actually want to achieve, you need to use the projection to get the ID and then use another query to retrieve the object.
Criteria idQuery = session.createCriteria(Story.class);
idQuery.add(Restrictions.ge("id", 2));
idQuery.setProjection(Projections.min("id"));
int returnedId = criteria.uniqueResult();
Criteria storyQuery = session.createCriteria(Story.class);
storyQuery.add(Restrictions.idEq(returnedId);
Story story = (Story) storyQuery.uniqueResult();
return story;

How to avoid hibernate default order by id?

I make this query:
String query = FROM Account acc WHERE acc.id = ? OR acc.id = ? or acc.id = ?...
I have array of ids:
long[] accountIds= {327913,327652,327910,330511,330643};
Then I make
getHibernateTemplate().find(query, accountIds);
I see that the list of accounts I get back from this query is:
327652,327910,327913,330511,330643, obviously , ordered by id.
Any chance I get it back in the order I wrote the ids?
Will appreciate all the help
You may want to use Criteria and its addOrder.
Something like this:
DetachedCriteria cr = DetachedCriteria.forClass(entityClass);
//Add expressions or restrictions to your citeria
//And add your ordering
cr.addOrder(Order.asc("yourID"));
List<T> ls = getHibernateTemplate().findByCriteria(cr);
return ls;
You can't do it on query level.
You can sort after loading from db, something like this
long[] accountIds= {327913,327652,327910,330511,330643};
List<Account> afterHql = getHibernateTemplate().find(query, accountIds);
List<Account> sortedList = new ArrayList<Acount>();
for (long id : accountIds)
{
for (Account account : afterHql)
{
if (account.getId() == id)
{
sortedList.add(account);
}
}
}
It is not possible to fetch results by providing any entity in OR Query or Restrictions.in(). As by deafult when you fire this kind of query it will search for the results id wise. So it will give you results id wise only. You can change the order by using Criteria either in asc or desc. And if you want to have results as per you enter id, then second answer is the only option.
You can only order by column values returned by the query, in a sequence defined by the data type . Wouldn't it be better to pre-order the IDs you supply, and order the query result by ID, so they come out in the same order?

Categories