如何以较少的开销检索作为另一个实体的属性的实体?

时间:2015-03-31 08:48:02

标签: hibernate jpa hql

我有以下实体:

@Entity
public class A{
      ...
      @ManyToOne( optional=false, fetch=FetchType.LAZY )
      @NotFound( action=NotFoundAction.EXCEPTION )
      @JoinColumn( name="ID_CLASSB", nullable=false, insertable=true,  updatable=true )
      private B b;
      ...
      private String anIdentifier;
      ...
      @OneToMany(fetch=FetchType.LAZY)...
      private List<C> manyObjects;
      ...
      @OneToMany(fetch=FetchType.LAZY)...
      private List<D> soMany;
}

如您所见,实体B是实体A中的属性。

B实体没有对A实体的引用,它由简单属性构成:

@Entity
public class B{

   @Column(...)
   private String field1;

   @Column(...)
   private int field2;
   ...
}

现在,我想从“anIdentifier”属性与特定值匹配的A实体中检索所有B实体。 我现在的疑问是:

"select a.b from A a where a.anIdentifier='identifier'"

问题是第二个查询特别慢......我想这是因为在提取实体B之前,hibernate仍会创建整个实体A(以及它的所有属性)。

那么,是否有另一种最有效的方法来实现我的目标?

1 个答案:

答案 0 :(得分:1)

这是一个简单的查询,应该可以快速运行。提取A或不提取的事实不会影响它,因为关系将被延迟加载(尽管A可能未被提取)

它缓慢的典型原因是: - 没有关于A到B关系的外键索引(表A的ID_CLASSB), - 你在DB中有很多As而anIdentifier没有索引

首先检查它们在DB中的存在。

通常,您需要能够看到生成的sql能够推理(并测试)性能。 你可以查看这个答案如何完成hibernate How to print a query string with parameter values when using Hibernate

一旦有了真正的查询,就可以在数据库中进行测试,例如在MySQL中,这是解释命令。