I have two tables, Org and Project, linked by a many-to-many association. I want to find all Orgs with no associated Project. I'm trying to use Criteria for efficiency and safety, but it's not working.
So far I've tried:
Code:
Criteria org = session.createCriteria(Org.class);
org.add(Restrictions.eq("projects", java.util.Collections.EMPTY_SET));
org.list();
org = session.createCriteria(Org.class);
org.add(Restrictions.eq("projects", null));
org.list();
Criteria org = session.createCriteria(Org.class);
org.add(Restrictions.eq("projects.id", null));
org.list();
I get exceptions like this:
Code:
org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.doList(Loader.java:2235)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)
at org.hibernate.loader.Loader.list(Loader.java:2124)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:117)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1706)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:315)
at org.wfp.rita.datafacade.HibernateReferenceEqualsNullTest.testDataCarrier(HibernateReferenceEqualsNullTest.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.SQLException: No value specified for parameter 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
at com.mysql.jdbc.PreparedStatement.checkAllParametersSet(PreparedStatement.java:2513)
at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2489)
at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2415)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2169)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1810)
at org.hibernate.loader.Loader.doQuery(Loader.java:695)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:257)
at org.hibernate.loader.Loader.doList(Loader.java:2232)
... 21 more
The actual query that's being run is:
Code:
09:22:10,423 DEBUG SQL: select this_.id as id0_0_ from org this_ where this_.id=?
com.mysql.jdbc.JDBC4PreparedStatement@15d17d7: select this_.id as id0_0_ from org this_ where this_.id=** NOT SPECIFIED **
09:22:10,498 WARN JDBCExceptionReporter: SQL Error: 0, SQLState: 07001
09:22:10,499 ERROR JDBCExceptionReporter: No value specified for parameter 1
So it appears that Hibernate is:
- not joining the project table
- querying against the wrong table (org.id instead of project.id)
- failing to set the parameter
What am I doing wrong? How is this supposed to work?
The test case is
here.