Ответ 1
Вы должны установить явное выделение также для "подзапросов".
rpSubQ.select(subQRoot);
Я пытаюсь найти всех пользователей для папки, в которой пользователь был создан после определенной даты. связь между пользователем и папкой живет в отдельной таблице.
Это запрос, с которым я столкнулся, но это исключает
Никакой явный выбор и неявный холод не определяется
Код
@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;
}
Кто-нибудь знает, почему это не работает?
Вы должны установить явное выделение также для "подзапросов".
rpSubQ.select(subQRoot);
Сегодня у меня была такая же ошибка. Самое забавное, что я схватил свой пример из Hibernate 3.6.3.Final docs. Их пример:
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 ) );
То, что я сделал для "исправления" ошибки, явно выбирает корень. Я должен был создать один корень, чтобы решить эту проблему. Вот мой пример:
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 ) );
То, что я не могу понять, является причиной того, что неявный выбор не может быть выполнен. В примере Hibernate единственным классом, который используется, является Person.class. Я обновляю свой ответ, когда я копаю немного дальше.