JPA 2 无显式选择且隐式冷无法确定

发布于 2024-11-02 08:26:53 字数 1755 浏览 1 评论 0原文

我正在尝试获取某个文件夹中的所有用户,该用户是在特定日期之后创建的。用户和文件夹之间的关系位于单独的表中。

这是我提出的查询,但它引发了异常

无显式选择且隐式冷端未确定

代码

@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;
}

有人知道为什么这不起作用吗?

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 separate table.

This is the query I came up with but it throws 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你的呼吸 2024-11-09 08:26:53

您还应该为“子查询”明确设置选择。

rpSubQ.select(subQRoot);

You should set explicitly selection also for "subqueries".

rpSubQ.select(subQRoot);
如梦亦如幻 2024-11-09 08:26:53

我今天遇到了完全相同的错误。有趣的是,我从 Hibernate 3.6.3.Final 文档中获取了示例。他们的例子是:

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。当我进一步挖掘时,我会更新我的回复。

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.

迷迭香的记忆 2024-11-09 08:26:53

查询 roots 指定其上的域对象查询被评估。查询根是 Root 接口的实例,必须显式声明,因此

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type);
list.forEach(i -> entityManager
         .createQuery(criteriaQuery.where(
              criteriaBuilder.equal(criteriaQuery.from(type).get(field), i))).getResultList());

您必须将 root 显式定义为

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type);
Root<T> root = criteriaQuery.from(type);
list.forEach(i -> entityManager
        .createQuery(criteriaQuery.where(
            criteriaBuilder.equal(root.get(field), i))).getResultList());

Query roots specify the domain objects on which the query is evaluated. Query root is an instance of the Root interface and must explicitly declared, so instead of this

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type);
list.forEach(i -> entityManager
         .createQuery(criteriaQuery.where(
              criteriaBuilder.equal(criteriaQuery.from(type).get(field), i))).getResultList());

You must explicitly define root as

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type);
Root<T> root = criteriaQuery.from(type);
list.forEach(i -> entityManager
        .createQuery(criteriaQuery.where(
            criteriaBuilder.equal(root.get(field), i))).getResultList());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文