当前位置: 首页 > 知识库问答 >
问题:

JPA标准生成器OneToMany限制

许自强
2023-03-14

我有一个父表,它与一个子表有许多关联。

我试图用CriteriaBuilder编写一个查询,以限制从子表返回的结果。

我添加了一个谓词,类似于

cb.equal(parent.get("children").get("sex"), "MALE")

如果父节点有一个子节点或子节点和子节点,则返回父节点,同时也返回所有子节点。

Hibernate使用我的谓词启动了第一个查询,但是第二个获取孩子的查询只使用了where子句中的JoinColumn,而没有包含它

cb.equal(parent.get("children").get("sex"), "MALE").

思想?

我正在使用SetJoin

children = parent.joinSet("children", JoinType.LEFT)

澄清:

public static Specification<Parent> findPlanBenefits(Integer parentId) {
    return (parent, query, cb) -> {
        Predicate predicates = cb.conjunction();
        List<Expression<Boolean>> expressions = predicates.getExpressions();

        //Parent Criteria
        expressions.add(cb.equal(parent.get("parentId"), parentId));

        //Children Criteria
        SetJoin<Parent, Children> children = parent.joinSet("children", JoinType.LEFT);

        Predicate sex = cb.equal(children.get("sex"), "MALE");
        children.on(sex);

        return predicates;
    };
}

共有3个答案

郏兴贤
2023-03-14

为了将来的参考,这是另一篇帮助我的帖子(链接):而不是家长。joinSet使用fetch,然后将其强制转换为join:

Join<Parent, Children> join = (Join<Parent, Children>)parent.fetch(Parent_.children);

正如上面链接的帖子中提到的,这不是完美的解决方案,但它为我节省了很多麻烦。

凤柏
2023-03-14

当您创建< code>JOIN(尤其是当属性是集合类型,而不是< code>SingularAttribute)时,您必须使用它来构建条件,因此使用

cb.equal(children.get("sex"), "MALE").

而不是

cb.equal(parent.get("children").get("sex"), "MALE").
安高翰
2023-03-14

恐怕JOIN ON不能像您在答案中期望的那样工作。JOIN ON只告诉如何加入,而不是如何加载关系。

因此,为了解决您的问题,您必须在加载子项后对其进行过滤,或者使用单独的查询手动获取所有男性子项。

为了检查 JOIN ON 的工作原理,您还可以尝试相应的 JPQL 查询。

更新

OP告诉我们,JPQL查询<code>从父p中选择p,并连接到fetch子c,其中p.parentId=:parentId和c.sex=“MALE”

相应的CriteriaQuery如下所示:

CriteriaQuery<Parent> criteria = cb.createQuery((Class<Parent>) Parent.class);
Root<Parent> parent = criteria.from(Parent.class);

criteria.select((Selection<T>) parent);
SetJoin<Parent, Children> children = parent.joinSet("children", JoinType.LEFT);

Predicate sexPredicate = cb.equal(children.get("sex"), "MALE");
parent.fetch(children);
//parent.fetch("children");//try also this

criteria.where(sexPredicate);
 类似资料:
  • 我正在尝试执行一些过滤,但ManyToOne的过滤有一些问题,每次我得到结果集时,我都会得到所有Task对象,而不管它们所链接的项目如何。我有以下实体: 和任务类,它通过它的id与项目链接 在任务表中,它看起来像这样 我有jparepository来搜索任务: 以及使用由org . hibernate . jpamodelgen . jpametamodelentityprocessor生成的元模

  • Movie类有一个他的会话列表,我想同时保存存储在列表中的电影和他的会话。 这是我的代码 Hibernate不会引发异常,movie和session都成功地持久化了,但是表session中的外键'movie_id'始终显示为null。 那么问题出在哪里?当我只使用@onetomany而不使用@manytoone时,同样的测试工作正常,外键被成功添加。

  • 问题内容: 我一直在尝试查找JPA Criteria API教程,但是并没有取得太大的成功。您了解任何初学者吗?我想开始在Java5 / Maven应用中使用它来构建复杂的搜索查询。 问题答案: JPA2.0中的动态,类型安全查询在这一主题上是一个很好的查询,实际上是到目前为止我在 网上 找到的最好的查询,甚至比Java EE 6教程第23章使用Criteria API创建查询更好(包含一些错误)

  • 我正在尝试实现以下内容: 问:我如何用JPA 2标准实现这个? 我可以单独获得asCount结果,但不知道如何将其加入公司 提前感谢。 PS 1。有一个类似的线程使用HiberNate应用编程接口询问子级计数:HiberNate子级计数标准 2。另一个描述该主题的有用线程: JPA CriteriaBuilder——按一对多关系中关联实体的数量排序

  • 主要内容:标准Having示例HAVING子句与GROUP BY子句一起用于过滤表中的数据。 在Criteria API中,Abstract接口的方法用于设置分组数据的条件。 标准Having示例 在这里,我们将在表上执行多个操作。假设该表包含以下记录 - 现在,请按照以下步骤执行操作: - 第1步: 创建一个实体类。在包下创建了类文件。 该类包含三个属性:,,以及所有必需的注解。 文件:StudentEntity.java

  • 主要内容:标准WHERE示例WHERE子句用于对数据库应用条件并基于该条件获取数据。 在Criteria API中,AbstractQuery接口的)方法用于设置查询条件。 标准WHERE示例 在这里,我们将在表上执行多个操作。假设该表包含以下记录 - 现在,请按照以下步骤执行操作: - 第1步: 创建一个实体类。在包下创建了类文件。 该类包含三个属性:,,以及所有必需的注解。 文件:StudentEntity.java -