【发布时间】:2013-12-22 16:46:35
【问题描述】:
当前项目在 Spring + Openjpa + Roo 上运行。我有这样的实体
public class Zoo{
....
@OneToMany(mappedBy="zoo", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private List<Elephant> elephants;
@OneToMany(mappedBy="zoo", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private List<Jaguar> jaguars;
@OneToMany(mappedBy="zoo", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private List<Tiger> tigers;
....
}
然后我有一个简单的 UI 页面,只是试图更新 Zoo 名称,但是在简单查询之后来自 SQL 跟踪日志
SELECT t0.id, t0.name
FROM Zoo t0
WHERE t0.id = ?
有这样的查询
SELECT * FROM Zoo, Tiger, TigerProduct, TigerFood, FoodSupplier, SupplierContacts...
还有数百个这样的查询:
SELECT * FROM TigerProduct where tiger.id =: id_1
.....
SELECT * FROM TigerProduct where tiger.id =: id_n
....
....
SELECT * FROM TigerFood where tiger.id =: id_1
....
SELECT * FROM TigerFood where tiger.id =: id_n
Jaguar 和 Elephant 也是如此。当数据库中有大量数据时,这使得这个简单的操作变得非常慢。
第一个查询和后面的查询的 java 代码非常简单:
public static Zoo findZoo(Long id) {
if (id == null) return null;
return entityManager().find(Zoo.class, id);
}
从上面看,@OneToMany 关系上的默认 FetchType.Lazy 一点也不懒惰,以至于 JPA 试图提取链上的所有数据。
那么发生了什么以及如何清除这种情况?我只喜欢第一个查询,就是这样
【问题讨论】:
-
我不明白:
entityManager().find(Zoo.class, id)是否也运行所有这些查询?您是否尝试过明确指定FetchType.LAZY(认为没有帮助)?您是否尝试过降级/升级 OpenJPA(因为在我看来,该实现中存在性能问题)? -
@Andrei 我是的,在 java 代码中我确实指定了 FetchType.LAZY,但它并没有像您预期的那样帮助。你也是正确的,没有人对 UI 上的简单请求等一分钟返回结果感到满意。我们的 openjpa 已经是最新的了……但我在任何地方都找不到任何关于这种行为的线程或文章,让我觉得我的应用程序有错误,但 OpenJPA 没有。
-
所以当你调用
em.find()时你会得到同样的行为?您是否尝试过降级 OpenJPA? -
发布你的 persistence.xml 的内容。
标签: spring jakarta-ee jpa ejb openjpa