jpa避免查询

时间:2011-01-20 15:32:22

标签: jpa eclipselink

我有下一堂课

@Entity    
@Table(name = "table_order")    
@IdClass(OrderPK.class)    
public class Order {    
   /** Unique identifier of the currency code in which the transaction was negociated. */

@Column(name = "TRADECURRE", nullable = false, length = 5)    
  private String tradeCurrencyCode;

/** Currency Entity for Trade. */    
  @ManyToOne(optional = true, fetch = FetchType.LAZY)    
  @JoinColumns({     
     @JoinColumn(name = "TRADECURRE", referencedColumnName = "codigo", updatable = false, insertable = false) })    
  private Currency currencyEntity;

.. here get and sets    
}

然后执行下一个查询:

StringBuilder jpaQuery = new StringBuilder();

StringBuilder whereClause = new StringBuilder();

jpaQuery.append("SELECT o, o.currencyEntity");

List orders = query.getResultList();

在这一点上,jpa的日志显示2个查询执行,一个到订单表,另一个到货币表。

下面我写下一个代码(与前面代码相同的类和方法)

for (Object orderElement : orders) {

  int indexArray = 0;
  Object[] orderArray = (Object[]) orderElement;
  Order orderEntity = (Order) orderArray [indexArray++];
  orderEntity.setCurrencyEntity((Currency) orderArray [indexArray++]);

}

当行

orderEntity.setCurrencyEntity((Currency) orderArray [indexArray++]);
执行

,在数据库上再次执行对表货币的查询。我需要避免这个查询来修复一些性能问题,我在orderArray中有所有数据。

我正在使用eclipselink 1.1

提前致谢

1 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为您没有告诉JPA在初始选择中预取currentEntity(尽管我认为这是尝试SELECT o, o.currencyEntity做的事情})。因此,JPA每次循环都必须获取currentEntity,这是一个真正的性能杀手。

使用JPA执行此操作的方法是使用获取连接documented here)。你可以这样编写你的查询:

SELECT o from Order o LEFT JOIN FETCH o.currencyEntity

这也使得导航结果集比使用SELECT o, o.currencyEntity更容易,因为您只返回一个实体,其currencyEntity属性保持不变:

List<Order> orders = query.getResultList();
for (Order order : orders) {
    // fully-populated, without requiring another database query
    Currency ccy = order.getCurrentEntity(); 
}