我有下一堂课
@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
提前致谢
答案 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();
}