产品可以有一个或多个子产品形成树状结构。子产品也将引用父产品。在我的测试代码中,我创建了1个父项(mortgage
),其中包含2个子项(ml and me
)。为什么我尝试加载正确使用连接的父Product entity = (Product) hibernateTemplate.get(Product.class, mortgage.getId());
。
然而,hibernate也试图加载ml and me
的孩子,即使他们都没有孩子。有没有办法避免这种情况,这样我就可以将查询数量从3减少到1。
生成的SQL使用动态生成的别名,如children0_
。有没有办法可以让hibernate使用我自己的别名来说'p'
这是我的hbm和测试代码。
HBM
<class name="Product" table="PRODUCT">
<id name="id" type="java.lang.Long" column="ID">
<generator class="native">
<param name="sequence">PRODUCT_SN</param>
</generator>
</id>
<many-to-one name="parent" class="Product" lazy="false" column="PARENT" />
<set name="children" lazy="false" fetch="join" table="PRODUCT" cascade="all">
<key>
<column name="PARENT" />
</key>
<one-to-many class="Product" />
</set>
<property name="code" type="java.lang.String" column="CODE" not-null="true" />
<property name="name" type="java.lang.String" column="NAME" />
<property name="startDate" type="java.util.Date" column="STARTDATE" />
<property name="endDate" type="java.util.Date" column="ENDDATE" />
<property name="decisionable" type="boolean" column="ISDECISIONABLE" />
<property name="selectable" type="boolean" column="ISSELECTABLE" />
</class>
测试
public class ProductTest extends HibernateTestCase
{
@Test
public void save()
{
// Level 1 - mortgage LOB
Product mortgage = new Product();
mortgage.setCode("Mortgage");
Product ml = new Product();
ml.setCode("Mortgage Loan");
Product me = new Product();
me.setCode("Home Equity LOC");
mortgage.addChild(ml);
mortgage.addChild(me);
hibernateTemplate.save(mortgage);
Product entity = (Product) hibernateTemplate.get(Product.class, mortgage.getId());
}
}
LOG
Hibernate: select product0_.ID as ID0_1_, product0_.PARENT as PARENT0_1_, product0_.CODE as CODE0_1_, product0_.NAME as NAME0_1_, product0_.STARTDATE as STARTDATE0_1_, product0_.ENDDATE as ENDDATE0_1_, product0_.ISDECISIONABLE as ISDECISI7_0_1_, product0_.ISSELECTABLE as ISSELECT8_0_1_, children1_.PARENT as PARENT3_, children1_.ID as ID3_, children1_.ID as ID0_0_, children1_.PARENT as PARENT0_0_, children1_.CODE as CODE0_0_, children1_.NAME as NAME0_0_, children1_.STARTDATE as STARTDATE0_0_, children1_.ENDDATE as ENDDATE0_0_, children1_.ISDECISIONABLE as ISDECISI7_0_0_, children1_.ISSELECTABLE as ISSELECT8_0_0_ from PRODUCT product0_ left outer join PRODUCT children1_ on product0_.ID=children1_.PARENT where product0_.ID=?
DEBUG [org.hibernate.type.LongType] binding '1' to parameter: 1
DEBUG [org.hibernate.type.LongType] returning '2' as column: ID0_0_
DEBUG [org.hibernate.type.LongType] returning '1' as column: PARENT0_0_
DEBUG [org.hibernate.type.StringType] returning 'Mortgage Loan' as column: CODE0_0_
DEBUG [org.hibernate.type.StringType] returning null as column: NAME0_0_
DEBUG [org.hibernate.type.TimestampType] returning null as column: STARTDATE0_0_
DEBUG [org.hibernate.type.TimestampType] returning null as column: ENDDATE0_0_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISDECISI7_0_0_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISSELECT8_0_0_
DEBUG [org.hibernate.type.LongType] returning null as column: PARENT0_1_
DEBUG [org.hibernate.type.StringType] returning 'Mortgage' as column: CODE0_1_
DEBUG [org.hibernate.type.StringType] returning null as column: NAME0_1_
DEBUG [org.hibernate.type.TimestampType] returning null as column: STARTDATE0_1_
DEBUG [org.hibernate.type.TimestampType] returning null as column: ENDDATE0_1_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISDECISI7_0_1_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISSELECT8_0_1_
DEBUG [org.hibernate.type.LongType] returning '1' as column: PARENT3_
DEBUG [org.hibernate.type.LongType] returning '2' as column: ID3_
DEBUG [org.hibernate.type.LongType] returning '3' as column: ID0_0_
DEBUG [org.hibernate.type.LongType] returning '1' as column: PARENT0_0_
DEBUG [org.hibernate.type.StringType] returning 'Home Equity LOC' as column: CODE0_0_
DEBUG [org.hibernate.type.StringType] returning null as column: NAME0_0_
DEBUG [org.hibernate.type.TimestampType] returning null as column: STARTDATE0_0_
DEBUG [org.hibernate.type.TimestampType] returning null as column: ENDDATE0_0_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISDECISI7_0_0_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISSELECT8_0_0_
DEBUG [org.hibernate.type.LongType] returning '1' as column: PARENT3_
DEBUG [org.hibernate.type.LongType] returning '3' as column: ID3_
Hibernate: select children0_.PARENT as PARENT1_, children0_.ID as ID1_, children0_.ID as ID0_0_, children0_.PARENT as PARENT0_0_, children0_.CODE as CODE0_0_, children0_.NAME as NAME0_0_, children0_.STARTDATE as STARTDATE0_0_, children0_.ENDDATE as ENDDATE0_0_, children0_.ISDECISIONABLE as ISDECISI7_0_0_, children0_.ISSELECTABLE as ISSELECT8_0_0_ from PRODUCT children0_ where children0_.PARENT=?
DEBUG [org.hibernate.type.LongType] binding '3' to parameter: 1
Hibernate: select children0_.PARENT as PARENT1_, children0_.ID as ID1_, children0_.ID as ID0_0_, children0_.PARENT as PARENT0_0_, children0_.CODE as CODE0_0_, children0_.NAME as NAME0_0_, children0_.STARTDATE as STARTDATE0_0_, children0_.ENDDATE as ENDDATE0_0_, children0_.ISDECISIONABLE as ISDECISI7_0_0_, children0_.ISSELECTABLE as ISSELECT8_0_0_ from PRODUCT children0_ where children0_.PARENT=?
DEBUG [org.hibernate.type.LongType] binding '2' to parameter: 1
答案 0 :(得分:3)
您可能应该将关系标记为懒惰,以便仅在必要时加载子项。 如果要加载带有子节点的节点,请使用专用查询:
select p from Product left join fetch p.children where p.id = :id
答案 1 :(得分:1)
我认为您看到所有children
的原因是因为您在fetch="join"
中定义了<set name="children">
。如果删除它,我认为Hibernate只会提取Product
。