Java Hibernate Restcrition Criteria OR with DetachedCritera - java

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.

Related

QueryDSL order by subquery count

I want to implement the following SQL query with QueryDSL:
SELECT
*
FROM
a
ORDER BY (
SELECT
COUNT(*)
FROM
b
WHERE
b.a_id = a.id
AND b.c = 1) DESC
If I omit the criteria "b.c = 1", it's quite easy:
selectFrom(a).orderBy(a.bs.size().desc());
But I can't find a way (simple or not) to include a criteria in the subquery.
I want my QueryDSL query to return a List<A> and not Tuple, if possible.
Thanks in advance !

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

JPA select using IN

Here is my select from the database:
SELECT * FROM testlogging.employees
where
EMPLOYEE_NO in (
select EMPLOYEES_EMPLOYEE_NO from testlogging.test_logging
where ID in (
select TEST_LOGGING_ID from testlogging.test_logging_detail
where APPROVAL_LEVELS_ID = '4'
)
)
How would i do this in JPA?
SELECT e FROM Employees e ???
If you're asking for the JPA INsyntax you would do this:
SELECT e FROM Employees e where e.employee_no IN :employeelist
as well ass
query.setParameter( "employeelist" , yourlist );
and of course build yourlist accordingly. If you don't really need to parameterize the inner queries, you can disregard this and just go the straight forward route.
Cheers,
Just in case you're using the JPA Criteria metamodel queries, the IN usage goes like this
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
cq.where(pet.get(Pet_.color).in("brown", "black"));
as stated at http://docs.oracle.com/javaee/6/tutorial/doc/gjivm.html

Hibernate Criteria to find Duplicates

I want to get the duplicate entries. I want to use the query as criteria, for this i am using the below code.
SELECT * from A
WHERE field in (
SELECT field from A
GROUP BY field HAVING COUNT(field) > 1
);
The Hibernate mapping is like
#Entity
class A{
...
private String field;
...
}
How can I get list of A that have duplication in 'field' column?
You can pretty much translate your query one to one to HQL (warning: untested).
select A
from A a
where a.field in (
select ai.field
from A ai
group by ai.field -- assumes that by f you mean field
having count(a1.field) > 1
)
My own answer according prompted Anthony Accioly
final Criteria searchCriteria = session.createCriteria(A.class);
...
final DetachedCriteria d1 = DetachedCriteria.forClass(A.class);
d1.setProjection(Projections.count("field"));
d1.add(Restrictions.eqProperty("field", "AA.field"));
final DetachedCriteria d2 = DetachedCriteria.forClass(A.class, "AA");
d2.setProjection(Projections.projectionList()
.add(Projections.groupProperty("field")));
d2.add(Subqueries.lt(1L, d1));
criteria.add(Property.forName("field").in(d2));

Hibernate Criteria Left Joining Two Tables

I have two entities, say Business and Area.
Relevant properties:
Business - area, area2, code
Area - areaId, areaName
area and area2 of Business map to the id in Area
I'm trying to write a Hibernate criteria that returns all the areas with businesses only.
SQL looks like:
FROM area a LEFT OUTER JOIN business b on a.areaId = b.area or a.areaId = b.area2
WHERE b.code != null
GROUP BY a.areaName
This is what I have:
DetachedCriteria criteria = DetachedCriteria.forClass(Business.class)
.setProjection(Property.forName("area"))
.setProjection(Property.forName("area2"))
.add(Restrictions.ne("code", null));
Criteria criteriaArea = fullTextSession.createCriteria(Area.class)
.createAlias("areaId", "areaId", CriteriaSpecification.LEFT_JOIN)
.add(Property.forName("areaId").in(criteria));
But this doesn't work, I get a "not an association: areaId" query exception.
Any ideas why this is happening? Thanks.
createAlias() joins another entity using provided property. Hibernate calculates what table to join using mapping of provided property. But areaId isn't mapped as a #ManyToOne or #ManyToMany reference to Business entity. So Hibernate doesn't understand to what table you want to join using Area.areaId.
Your criteria will be translated to SQL like:
select a.* from Area a
left join <here should be table referenced by areaId> b on a.areaId = b.id
where a.areaId in (
select area, area2 from Business where code <> null
)
You may rewrite query without unused join:
DetachedCriteria criteria1 = DetachedCriteria.forClass(Business.class)
.setProjection(Property.forName("area"));
DetachedCriteria criteria2 = DetachedCriteria.forClass(Business.class)
.setProjection(Property.forName("area2"));
Criteria criteriaArea = fullTextSession.createCriteria(Area.class)
.add(Restrictions.or(
Property.forName("areaId").in(criteria1),
Property.forName("areaId").in(criteria2)
);

Categories