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

如何在Hibernate中使用JPA标准API摆脱N 1

方恺
2023-03-14

我正在将我们的DAO从使用Hibernate Criteria API迁移到JPA Criteria API。我有一个包含多个@ManyToOne的类:

@Entity
@Table(name = "A_TABLE", schema="SCHEMA_NAME")
public class A {
    @ManyToOne
    @JoinFormula("(SELECT * FROM (SELECT B.B_ID FROM SCHEMA_NAME.B_TABLE B WHERE B.A_ID = B_ID AND (B.B_CODE = '1' OR B.B_CODE = '2') ORDER BY B.B_CREATED_TIMESTAMP DESC) WHERE ROWNUM = 1)")
    private B b1;
    @ManyToOne
    @JoinFormula("(SELECT * FROM (SELECT B.B_ID FROM SCHEMA_NAME.B_TABLE B WHERE B.A_ID = B_ID AND (B.B_CODE = '3' OR B.B_CODE = '4') ORDER BY B.B_CREATED_TIMESTAMP DESC) WHERE ROWNUM = 1)")
    private B b2;
    ...
}

@Entity
@Table(name = "B_TABLE", schema="SCHEMA_NAME")
public class B {

}

在查询中,我使用的是JoinType。左键以消除默认生成的交叉连接:

if (LEFT_OUTER_JOIN_ENTITIES.contains(field)) {
    path = ((From) path).join(field, JoinType.LEFT);
} else {
    path = path.get(field);
}

我得到了正确的结果,所有的A和B记录都得到了正确的检索。然而,在迁移之后,我遇到了一个问题:尽管在生成的查询中使用了左外连接,但所有的记录都是逐个检索的。以前(使用Hibernate Criteria API时),Hibernate能够满足查询,而无需在生成的SQL中使用相同的连接。

感谢您的任何想法和帮助!

UPDATE作为使用上面的if-etc按“b1.field名称”搜索的示例,我会得到以下结果:

criteriaBuilder.equal(root.join("b1", JoinType.LEFT).get("someFiled"), 42)

共有1个答案

李烨
2023-03-14

N 1问题来自默认的FetchType。多通关联的急切抓取策略。

所以,你需要切换到FetchType。LAZY,像这样:

@ManyToOne(fetch = FetchType.LAZY)
@JoinFormula("(SELECT * FROM (SELECT B.B_ID FROM SCHEMA_NAME.B_TABLE B WHERE B.A_ID = B_ID AND (B.B_CODE = '1' OR B.B_CODE = '2') ORDER BY B.B_CREATED_TIMESTAMP DESC) WHERE ROWNUM = 1)")
private B b1;

@ManyToOne(fetch = FetchType.LAZY)
@JoinFormula("(SELECT * FROM (SELECT B.B_ID FROM SCHEMA_NAME.B_TABLE B WHERE B.A_ID = B_ID AND (B.B_CODE = '3' OR B.B_CODE = '4') ORDER BY B.B_CREATED_TIMESTAMP DESC) WHERE ROWNUM = 1)")
private B b2;

如果要自动检测可能影响应用程序其他部分的N 1问题,则可以使用数据源代理。

如果您迫切需要使用Criteria API获取关联,那么应该使用fetch,而不是join

if (LEFT_OUTER_JOIN_ENTITIES.contains(field)) {
    path = ((From) path).fetch(field, JoinType.LEFT);
} else {
    path = path.get(field);
}
 类似资料:
  • 问题内容: 到目前为止,给我带来了很多麻烦,所以我想摆脱它。尽管spring框架文档清楚地说明了应该做的事情,但实际上 并没有摘要列表。 所以我一直坚持删除并得到错误 -在名称为的中找不到带有请求的映射 对于所有应该由控制器类解决的Url(在这种情况下:)。有什么建议可以让我了解更多信息吗?我非常想知道到底由代表什么标签。 问题答案: 你可以用来自定义定义的每个bean 。现在,javadocs详

  • 问题内容: 到现在为止,给我造成了很多麻烦,所以我想摆脱它。尽管spring框架文档清楚地说明了应该做的事情,但实际上 并没有摘要列表。 所以我坚持删除并现在得到错误 WARN osweb.servlet.PageNotFound-在DispatcherServlet中,名称为’workoutsensor’的URI [/ webapp / trainees]的HTTP请求未找到映射 对于所有应该由

  • 问题内容: 我们正在使用iText从Java代码生成PDF文件,该文件在大多数情况下效果很好。几天前,我们开始生成PDF / A,而不是需要嵌入所有字体的普通PDF文件。iText 主要是自定义类和其他类的构建,在这些类中我们直接控制字体。所有使用的字体都是通过通过以下代码加载的TTF文件创建的- 效果很好: 现在,我们在使用HTML代码生成的PDF中使用一种特定的内容类型。我们使用来处理该部分。

  • 此查询用于检索一对多关系中的最后记录(请参阅SQL连接:选择一对多关系中的最后记录) 我的问题是:如何使用jpa criteria api使用subselect构建这个连接?可能吗?如果没有,可以使用jpql吗? 到目前为止我的代码:

  • 我用全屏独占模式(FSEM)准备了一个程序。我将JFrame的装饰特性设置为“未装饰”,以去掉标题栏和所有的插图。 我的代码是: 然而,标题栏令人烦恼地留在那里。我如何摆脱它?我需要手动设置所有插页吗?

  • 我想使用hibernate标准删除表中的所有记录,比如 我得到了以下很多帮助 是否有任何方法可以使用Criteria类或任何其他我可以使用的类来截断?请告诉我