From b6a0653a3ce5047eb2bea8098fa3ca1e91770138 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 17 Dec 2014 23:05:53 +1300 Subject: [PATCH] Fix for #223 - RawSql that includes a OneToMany not working --- .../server/deploy/BeanPropertyAssocMany.java | 4 ++ .../server/deploy/BeanPropertyAssocOne.java | 1 - .../ebeaninternal/server/query/SqlTree.java | 3 + .../tests/rawsql/TestRawSqlMasterDetail.java | 63 +++++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/avaje/tests/rawsql/TestRawSqlMasterDetail.java diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java index c781738cd..e557e4422 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java @@ -225,6 +225,10 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc { return createElPropertyValue(propName, remainder, chain, propertyDeploy); } + public void buildSelectExpressionChain(String prefix, List selectChain) { + // do not add to the selectChain at the top level of the Many bean + } + public SqlUpdate deleteByParentId(Object parentId, List parentIdist) { if (parentId != null) { return deleteByParentId(parentId); diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java index 6cc18b3ff..dcdc0bbe4 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java @@ -287,7 +287,6 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc { } } - /** * Return true if this a OneToOne property. Otherwise assumed ManyToOne. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTree.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTree.java index 4cff655b6..835b98a6b 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTree.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTree.java @@ -80,6 +80,9 @@ public class SqlTree { this.includes = null; } + /** + * Build a select expression chain for RawSql. + */ public List buildSelectExpressionChain() { ArrayList list = new ArrayList(); rootNode.buildSelectExpressionChain(list); diff --git a/src/test/java/com/avaje/tests/rawsql/TestRawSqlMasterDetail.java b/src/test/java/com/avaje/tests/rawsql/TestRawSqlMasterDetail.java new file mode 100644 index 000000000..8e8df67d7 --- /dev/null +++ b/src/test/java/com/avaje/tests/rawsql/TestRawSqlMasterDetail.java @@ -0,0 +1,63 @@ +package com.avaje.tests.rawsql; + +import com.avaje.ebean.BaseTestCase; +import com.avaje.ebean.Ebean; +import com.avaje.ebean.RawSql; +import com.avaje.ebean.RawSqlBuilder; +import com.avaje.tests.model.basic.Order; +import com.avaje.tests.model.basic.OrderDetail; +import com.avaje.tests.model.basic.ResetBasicData; +import org.junit.Test; + +import java.util.List; + +public class TestRawSqlMasterDetail extends BaseTestCase { + + @Test + public void test() { + + ResetBasicData.reset(); + + String rs = "select t0.id, t0.status, t1.id, t1.name, "+ + " t2.id, t2.order_qty, t3.id, t3.name " + + "from o_order t0 join o_customer t1 on t1.id = t0.kcustomer_id " + + "join o_order_detail t2 on t2.order_id = t0.id " + + "join o_product t3 on t3.id = t2.product_id " + + "where t0.id <= :maxOrderId and t3.id = :productId "+ + "order by t0.id, t2.id asc"; + + RawSql rawSql = RawSqlBuilder.parse(rs) + .columnMapping("t0.id", "id") + .columnMapping("t0.status", "status") + .columnMapping("t1.id", "customer.id") + .columnMapping("t1.name", "customer.name") + .columnMapping("t2.id", "details.id") + .columnMapping("t2.order_qty", "details.orderQty") + .columnMapping("t3.id", "details.product.id") + .columnMapping("t3.name", "details.product.name") + .create(); + + List ordersFromRaw = Ebean.find(Order.class) + .setRawSql(rawSql) + .setParameter("maxOrderId", 2) + .setParameter("productId", 1) + .findList(); + + printOrders(ordersFromRaw, "using RawSql"); + + } + + private void printOrders(List orders, String heading) { + System.out.println("-------------- "+heading); + for (Order order : orders) { + List details = order.getDetails(); + System.out.println("order: "+order.getId()+" "+order.getCustomer().getName()); + for (OrderDetail detail : details) { + System.out.println("detailId:" + detail.getId() + " productId:" + detail.getProduct().getId() + " qty:" + + detail.getOrderQty()); + } + } + System.out.println("-------------- "+heading+" complete"); + } +} +