JPA 2 No explicit selection and an implicit one cold not be determined
I am trying to fetch all users for a folder where the user was created after a certain date. the relationship between the user and the folder lives in a seperate table.
This is the query I came up with but it thorws the exception
No explicit selection and an implicit one cold not be determined
The code
@Override public List<RetailPostUserTbl> getNewUsersForSiteSince( Date date, Integer siteId ) { List<RetailPostUserTbl> toReturn = new ArrayList<RetailPostUserTbl>(); EntityManager em = getEntityManager(); CriteriaBuilder cb = em.getCriteriaBuilder(); Class<RpUserFolderMapTbl> userFolderPC = userFolderMapDAO.getPersistentClass(); CriteriaQuery<RpUserFolderMapTbl> mapQuery = cb.createQuery( userFolderPC ); Root<RpUserFolderMapTbl> root = mapQuery.from( userFolderPC ); Path<Integer> folderIdPath = root.get( RpUserFolderMapTbl_.folder ).get( FolderTbl_.folderId ); Predicate folderCondition = cb.equal( folderIdPath, siteId ); Subquery<RetailPostUserTbl> rpSubQ = mapQuery.subquery( persistentClass ); Root<RetailPostUserTbl> subQRoot = rpSubQ.from( persistentClass ); Path<UserTbl> userPath = subQRoot.get( RetailPostUserTbl_.user ); Path<Date> userCreatedPath = userPath.get( UserTbl_.userCreateDate ); Predicate userCreateDateCondition = cb.greaterThanOrEqualTo( userCreatedPath, date ); rpSubQ.where( userCreateDateCondition ); mapQuery.where( cb.and( folderCondition, cb.exists( rpSubQ ) ) ); TypedQuery<RpUserFolderMapTbl> query = em.createQuery( mapQuery ); List<RpUserFolderMapTbl> results = query.getResultList(); for ( RpUserFolderMapTbl result : results ) { RetailPostUserTbl rpuser = result.getUser().getRetailPostUser(); toReturn.add( rpuser ); } return toReturn; }
Anyone know why this is not working?
Answers
You should set explicitly selection also for "subqueries".
rpSubQ.select(subQRoot);
I had the exact same error today. The funny thing is that I grabbed my example from Hibernate 3.6.3.Final docs. Their example is:
CriteriaQuery query = builder.createQuery(); Root<Person> men = query.from( Person.class ); Root<Person> women = query.from( Person.class ); Predicate menRestriction = builder.and( builder.equal( men.get( Person_.gender ), Gender.MALE ), builder.equal( men.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE ) ); Predicate womenRestriction = builder.and( builder.equal( women.get( Person_.gender ), Gender.FEMALE ), builder.equal( women.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE ) ); query.where( builder.and( menRestriction, womenRestriction ) );
What I did to "fix" the error is explicitly select the root. Note I had to create one root to solve this. Here is my example:
CriteriaQuery query = builder.createQuery(); Root<Person> personRoot = query.from( Person.class ); Predicate menRestriction = builder.and( builder.equal( personRoot.get( Person_.gender ), Gender.MALE ), builder.equal( personRoot.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE ) ); Predicate womenRestriction = builder.and( builder.equal( personRoot.get( Person_.gender ), Gender.FEMALE ), builder.equal( personRoot.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE ) ); query.select(personRoot); query.where( builder.and( menRestriction, womenRestriction ) );
What I can't figure out is why an implicit selection could not be made. In Hibernate's example the only class that is used is Person.class. I'll update my response when I dig in a little further.
Need Your Help
How to create unit tests against non in-memory database such as MySQL in Play framework, with resetting to known state?
unit-testing playframework playframework-2.0 database-testing
I want to create unit tests that cover code that use relational database in Play framework 2.1.0. There are many possibilities for this and all cause problems: