JPA избежать запроса - PullRequest
       5

JPA избежать запроса

2 голосов
/ 20 января 2011

у меня следующий класс

@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++]);

выполняется, запрос к валюте таблицы выполняется еще раз в базе данных. Мне нужно избегать этого запроса, чтобы исправить некоторые проблемы с производительностью, у меня есть все данные в порядке массива.

Я использую eclipselink 1.1

заранее спасибо

1 Ответ

0 голосов
/ 21 января 2011

Это происходит потому, что вы не сказали JPA предварительно выбрать currentEntity при первоначальном выборе (хотя я думаю, что именно это вы пытались сделать с SELECT o, o.currencyEntity). В результате JPA вынужден извлекать currentEntity каждый раз в цикле, и это настоящий убийца производительности.

Способ сделать это с помощью JPA - извлечение соединения ( задокументировано здесь ). Вы бы написали свой запрос так:

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(); 
}
...