Hi,
I want to be able to load OneToMany collections with BATCH optimization and at the same time restrict the number of fields fetched from DB for both master and related entities.
For example, there are two entities Order and OrderLine:
@Entity
@Table(name = "ORDER")
public class Order extends BaseEntity {
@Column(name = "NUM")
private String num;
@Column(name = "DATE_")
private Date date;
@OneToMany(mappedBy = "order")
private List<OrderLine> orderLines;
// getters and setters
}
@Entity
@Table(name = "ORDER_LINE")
public class OrderLine extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ORDER_ID")
private Order order;
@Column(name = "NAME")
private String name;
@Column(name = "QUANTITY")
private Double quantity;
// getters and setters
}
Let's say we need only Order.num and OrderLine.quantity attributes to be loaded. So I wrote the following code:
@Test
public void testLoadOneToMany() throws Exception {
... // some preparation and transaction start
def query = em.createQuery('select o from Order o where o.id in ?1')
query.setParameter(1, orderIds)
FetchGroup orderFG = new FetchGroup()
orderFG.addAttribute('num')
orderFG.addAttribute('orderLines')
orderFG.addAttribute('orderLines.quantity')
orderFG.setShouldLoadAll(true)
query.setHint(QueryHints.FETCH_GROUP, orderFG)
query.setHint(QueryHints.BATCH, "o.orderLines") // leads to empty orderLines collection
def list = query.getResultList()
Order order = list[0]
... // transaction commit here
order = Support.reserialize(order) // emulates passing through network
assertNotNull(order.num)
assertFail { order.date }
assertNotNull(order.orderLines)
assertEquals(3, order.orderLines.size()) // fails here with BATCH fetch but OK with FETCH
}
EclipseLink executes two correct SQL statements but doesn't populate orderLines collection for some reason.
Interesting that if I change BATCH hint to FETCH for o.orderLines, the collection is populated correctly. And it also works with BATCH if I add back reference to order to the FetchGroup:
orderFG.addAttribute('orderLines.order')
orderFG.addAttribute('orderLines.order.num')
EclipseLink 2.5.2, shared cache is switched off.
I could live with FETCH hint in case of one collection is loaded, but BATCH must be much more effective with loading of more than one simultaneously. Creating back references looks like a strange workaround.
Can it be a bug, or something is wrong with my usage of FetchGroup and BATCH hint?
Thanks,
Konstantin
[Updated on: Fri, 19 December 2014 14:16]
Report message to a moderator