【发布时间】:2011-06-17 02:57:05
【问题描述】:
当我有一个包含地图的实体时,例如
@Entity
public class TestEntity {
@ElementCollection(fetch = FetchType.EAGER)
Map<String, String> strings = new HashMap<String, String>();
}
并且我选择了多个实体 (SELECT z FROM TestEntity z),OpenJPA 2.0 为每个 TestEntity 执行一个查询以获取地图,即使我使用了 FetchType.EAGER。当 Map 值是一个实体并且我使用 @OneToMany 而不是 @ElementCollection 时,也会发生这种情况。原则上,这可以通过一个查询来更有效地完成,该查询为所有返回的 TestEntities 选择所有映射条目。对于集合值字段,OpenJPA 已经默认执行此操作 (openjpa.jdbc.EagerFetchMode" value="parallel"),但它似乎在这个简单实体上失败了。(与 value="join" 相同的问题)。
我会做错什么吗?有没有一种简单的方法可以告诉 OpenJPA 不要对每个实体执行查询,而只执行一个查询? 或者是否已经有任何改进计划的工作(我在https://issues.apache.org/jira/browse/OPENJPA-1920 下提交)?
这对我们来说是个问题,因为我们希望使用 OpenJPA 获取(和分离)大约 1900 种产品的列表,这需要将近 15 秒。使用我自己的本机查询只需不到一秒钟的时间。
只需要编写一个原生查询不会有太大问题,但我们使用的映射位于可重用的 StringI18N 实体中,该实体引用自多个不同的实体(并且可以在对象图中很深),因此原生查询是一个维护头痛。 非常感谢任何提高性能的帮助。
编辑:明确使用 JOIN FETCH 也无济于事: “从 TestEntity z JOIN FETCH z.strings 中选择 z” OpenJPA 的 TRACE 仍然显示它为每个单独的 TestEntity 执行一个 SQL 语句。
【问题讨论】:
-
问题在使用 Hibernate 4.2 时看起来是一样的。
-
使用@BatchSize 注释可能会解决Hibernate 中的问题
-
已经尝试过了,但没有,但在我的情况下,我认为这是在加载我的实际 MultilingualText 实体时出现的@OneToOne 问题......我会继续搜索!
-
有趣的是,我实际上是在我的 StringI18N 实体中使用地图来实现相同的目标。我最终为我们使用的每种语言硬编码了一个字符串字段。 (没有暴露给 StringI18N 的客户,他们仍然使用 set(String, Locale) 方法)。这很难看,但我认为在我们的情况下它是可以接受的,因为语言永远不会改变。
-
是的,用法相同,但在我的情况下,我以前使用过另一种方法,这很痛苦(每次都创建自定义查询)。我已经发布了一个问题,希望尽快得到答复!
标签: performance jpa select map