Search code examples
hibernatedspace

Constructing a where exists subquery with hibernate


I am attempting to create the following query using hibernate.

select * from item 
where exists (
  select 1
  from metadatavalue mv
  where mv.dspace_object_id=item.uuid
  and text_value='No Date'
);

I am having difficulty constructing the subquery using hibernate objects.

The following code is working for me

Session session = (Session) context.getDBConnection().getSession();
Criteria criteria = session.createCriteria(Item.class, "item");
criteria.add(Restrictions.sqlRestriction("exists (select 1 from metadatavalue mv where mv.dspace_object_id=this_.uuid and text_value='No Date')"));

I would like to create this query with hibernate objects.

Session session = (Session) context.getDBConnection().getSession();
Criteria criteria = session.createCriteria(Item.class, "item");
DetachedCriteria subcriteria = DetachedCriteria.forClass(MetadataValue.class);
subcriteria.add(???)
criteria.add(Subqueries.exists(subcriteria));

I am unsure of the proper way to reference item.uuid (property name "id") from the subquery.

If I try the following

Criteria criteria = session.createCriteria(Item.class, "item");
DetachedCriteria subcriteria = DetachedCriteria.forClass(MetadataValue.class,"mv");
subcriteria.add(Property.forName("mv.dspace_object_id").eqProperty("item.uuid"));
criteria.add(Subqueries.exists(subcriteria));
System.out.println("xx" + criteria.list().size());

I get the following error

java.lang.NullPointerException
    at org.hibernate.loader.criteria.CriteriaQueryTranslator.getProjectedTypes(CriteriaQueryTranslator.java:401)
    at org.hibernate.criterion.SubqueryExpression.createAndSetInnerQuery(SubqueryExpression.java:152)
    at org.hibernate.criterion.SubqueryExpression.toSqlString(SubqueryExpression.java:68)
    at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:419)
    at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:123)
    at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:92)
    at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:95)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1604)
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
    at org.dspace.core.Test.main(Test.java:37)

[


Solution

  • Per the recommendations above, I used property names rather than column names and I added the projection. This resolved the issue.

    Criteria criteria = session.createCriteria(Item.class, "item");    
    DetachedCriteria subcriteria = DetachedCriteria.forClass(MetadataValue.class,"mv");
    subcriteria.add(Property.forName("mv.dSpaceObject").eqProperty("item.id"));
    subcriteria.setProjection(Projections.property("mv.dSpaceObject"));
    criteria.add(Subqueries.exists(subcriteria));
    System.out.println("xx" + criteria.list().size());