i have a simple Criteria like this
Student has only one School this is just a illustrative example.
private List<Student>getData()
{
final Session session = ...............
final Criteria criteria = session.createCriteria(Student.class);
final Criteria criteria2 = criteria.createCriteria("school","school",JoinType.LEFT_OUTER_JOIN,isNotNull("status"));
return criteria.list();
}
i need the Students even if they not have a School... but if they have the School i need the Status is not NULL.
i was wondering if this
criteria.createCriteria("school","school",JoinType.LEFT_OUTER_JOIN,isNotNull("status"));
filterings using left-outer-join are useless because i am getting the Schools with null status
but if i apply this
final Criteria criteria2 = criteria.createCriteria("school","school",JoinType.LEFT_OUTER_JOIN);
criteria2.add(isNotNull("status"));
it works or if i apply
criteria.createCriteria("school","school",JoinType.INNER_JOIN,isNotNull("status"));
works as well.
my question is
i should never put Criterions or filters in createCriteria o createAlias using left-Outer-Join are they just ignored or how can that be used?
what are the diffs between using in the ON or use the same criterions in regular criteria using .add(
any help is hugely appreciate.
Related
public List<AnswerValues> getAllAnswers(Forms fm){
Session sess = getSession();
Criteria crit = sess.createCriteria(FormQuestions.class);
crit.add(Restrictions.eq("fkformId",fm));
List<FormQuestions> qs = crit.list();
}
The code is incomplete. I want to do the below operation on the list qs.
FormQuestions fq;
fq.getFormsId();
How can I perform the above operation from the list?
I'm a beginner to java spring, any help will be considered a big help.
Assuming getFormsId is a getter (as you state in the comments):
qs.stream().map(fq -> fq.getFormsId()).collect(Collectors.toList());
will get you a list of whatever getFormsId returns from each of the FormQuestions.
In the django orm I can do something like the following:
people = Person.objects.filter(first_name='david')
for person in people:
print person.last_name
How would I do the equivalent in Java Hibernate's orm? So far, I've been able to do a single get, but not a filter clause:
Person p = session.get(Person.class, "david");
What would be the correct way to do this though?
you can use native SQL
session.beginTransaction();
Person p = getSingleResult(session.createNativeQuery("SELECT * FROM People where name = 'david'",Person.class));
session.getTransaction().commit();
and the function getSingleResult would be somthing like this :
public static <T> T getSingleResult(TypedQuery<T> query) {
query.setMaxResults(1);
List<T> list = query.getResultList();
if (list == null || list.isEmpty()) {
return null;
}
return list.get(0);
}
you can get a list like this :
List<Person> list = session
.createNativeQuery("SELECT * FROM People", Person.class)
.getResultList();
There are several approaches to do this so here goes:
Lazy way - possibly bad if you have a tons of data is to just load up
the whole list of persons, stream it and apply a filter to it to
filter out objects not matching the given first name.
Use a HQL query (Hibernate Query Language) to create a select query
https://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/chapters/query/hql/HQL.html
Use Hibernate's Criteria API to achieve the above
https://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/chapters/query/criteria/Criteria.html
Alternatively you can even use a native SQL query to do the above.
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();
Criteria criteria = session.createCriteria(TableA.class)
.add(Subqueries.propertyNotIn("id_a", DetachedCriteria.forClass(TableB.class)
.createAlias("id_a_from_tableB", "b")
setProjection(Property.forName("b.id_a"))));
I use this to get id_a from TableA if id_a is not in TableB. I need also get id_a if is in TableB but field "message" is not null.
I think this post can help you.
with criteria I think hibernate does not support UNION ALL but you
can use two criteria queries to get the expected result:
Criteria cr1 = session.createCriteria(Suppliers.class);
cr1.setProjection(Projections.projectionList()
.add( Projections.property("supplier_id"), "supplier_id" )
);
List results1 = cr1.list();
Criteria cr2 = session.createCriteria(Orders.class);
cr2.setProjection(Projections.projectionList()
.add( Projections.property("supplier_id"), "supplier_id" )
);
List results2 = cr2.list();
results1.add(results2);
List unionAllList = results1; //this is the expected result.
For example, you could add new criteria when you get from TableB if message is not null, and later just join two Java collections:
Criteria criteria1 = session.createCriteria(TableB.class)
.add( Restrictions.isNotNull("message")
P.S. Or I recommend using Criteria API from JPA2.1 (Chapter 6) instead of hibernate Criteria, because it's look like simple SQL and this solution is much more universally.
I have a detachedCriteria like this
private final DetachedCriteria DETACHED_CRITERIA_FOR_FILTERING_STUDENTS= DetachedCriteria.forClass(Students.class)
.add(filters)
.add(super.criterionForFilteringStudents)
.setProjection(idProjection())
.setResultTransformer(transformer(Students.class));
Later i use it like normally do i have a Table named RelationShip which have a Integer which is not a foreing key just a Integer column.
final Criteria criteria = session.createCriteria(RelationShip.class)
.add(filters)
.add(Subqueries.propertyIn("c03",DETACHED_CRITERIA_FOR_FILTERING_STUDENTS));
Everything works like a charm but i did realize that this query is completely cached i mean i used like this of course in a different context.
public List<Student>getStudents()
{
final Criteria criteria = session.createCriteria(Students.class)
.add(filters)
.add(super.criterionForFilteringStudents)
.setProjection(idProjection())
.setResultTransformer(transformer(Students.class))
.setCacheable(true)
.setCacheRegion(region);
return criteria.list();
}
Of course i could do something like
public List<RelationShip>getRelationShip()
{
final Criteria criteria = session.createCriteria(RelationShip.class)
.add(filters)
.add(Restrictions.in("c03",getStudents()));
return criteria.list();
}
But i came with this concern how could i use a DetachedCriteria which is a query which is completely cacheable or cached is this possible?
I have try
DETACHED_CRITERIA_FOR_FILTERING_STUDENTS.getExecutableCriteria(session).setCacheable(true).setCacheRegion(region)
But with no success.
Is this possible?