项目名称:shop_goods
使用spring ,hibernate,struts2,分别的版本如下:
spring :3.2.3.RELEASE
hibernate:4.2.2.Final
struts2:2.3.4.1
使用xml配置,使用maven构建。
这里涉及两个实体类:商品,超市。因为要讲解一对多的关系映射,所以假设商品和超市之间是多对一联系。
一个超市有多个商品,一个商品只属于一个超市。
实体类代码如下(省略setter,getter方法)
- package com.shop.jn.entity;
- import java.io.Serializable;
- import java.sql.Date;
- /**
- * entity:goods 商品
- * @author huangwei
- *
- */
- public class Goods implements Serializable{
- private static final long serialVersionUID = 586940311263079808L;
- private int id;
- /**
- * goods name
- */
- private String name;
- /**
- * alias of goods
- */
- private String alias;
- /**
- * when goods was brought
- */
- private java.util.Date buyDateTime;
- /**
- * when this record was modified
- */
- private Date latestModDateTime;
- /**
- * the price of goods
- */
- private double price;
- /**
- * the detail of the goods
- */
- private String description;
- /**
- * the supermarket the goods belong
- */
- private Supermarket supermarket;
- }
- package com.shop.jn.entity;
- import java.io.Serializable;
- import java.util.List;
- /**
- * entity:shop 超市
- * @author huangwei
- *
- */
- public class Supermarket implements Serializable{
- private static final long serialVersionUID = 6517742699077464699L;
- private int id;
- /**
- * the name of the shop
- */
- private String name;
- private String description;
- private List<Goods> goods;
- /**
- * the sum of goods
- */
- private int goodsAmount;
- }
hibernate配置文件如下
Goods.hbm.xml(多的一方):
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
- <hibernate-mapping>
- <class name="com.shop.jn.entity.Goods" table="t_goods" lazy="true">
- <!--<cache usage="read-write"/>
- --><id name="id" type="int">
- <column name="ID" precision="19" scale="0">
- <comment>主键id</comment>
- </column>
- <generator class="identity"/>
- </id>
- <property name="name">
- <column name="name">
- <comment>商品的名称</comment>
- </column>
- </property>
- <property name="alias" >
- <column name="alias">
- <comment>商品的别名</comment>
- </column>
- </property>
- <property name="buyDateTime">
- <column name="buyDateTime" >
- <comment>购买时间</comment>
- </column>
- </property>
- <property name="latestModDateTime">
- <column name="latestModDateTime">
- <comment>最后修改时间</comment>
- </column>
- </property>
- <property name="price">
- <column name="price">
- <comment>商品价格</comment>
- </column>
- </property>
- <property name="description">
- <column name="description">
- <comment>商品的具体信息</comment>
- </column>
- </property>
- <!-- fetch=FetchType.EAGER is equal lazy=false -->
- <many-to-one name="supermarket" class="com.shop.jn.entity.Supermarket" lazy="false" cascade="all" insert="true" update="true" >
- <column name="supermarketId" >
- <comment>商店</comment>
- </column>
- </many-to-one>
- </class>
- </hibernate-mapping>
Supermarket.hbm.xml(一的一方):
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
- <hibernate-mapping>
- <class name="com.shop.jn.entity.Supermarket" table="t_supermarket"
- lazy="true">
- <!--<cache usage="read-write"/> -->
- <id name="id" type="int">
- <column name="ID"><!-- precision="19" scale="0" -->
- <comment>主键id</comment>
- </column>
- <generator class="identity" />
- </id>
- <property name="name">
- <column name="name">
- <comment>商店的名称</comment>
- </column>
- </property>
- <!--<property name="goodsAmount"> <formula>(select count(*) from t_goods
- g where g.supermarketId=id)</formula> </property> -->
- <property name="description">
- <column name="description">
- <comment>商店的详细信息</comment>
- </column>
- </property>
- <bag name="goods" lazy="false" fetch="subselect" inverse="true">
- <key column="supermarketId"></key>
- <one-to-many class="com.shop.jn.entity.Goods" />
- </bag>
- </class>
- </hibernate-mapping>
主要对bag标签进行详细的说明
bag标签中有如下属性
lazy(可选--默认为 true)可以用来关闭延迟加载(false)
如果指定lazy为false,则在查询supermarket(一的一方)时会把supermarket中的goods(多的一方)也查询出来,查询的的策略有三种:subselect,select,join
这里使用的策略是fetch属性指定的subselect,执行的SQL语句如下:
- Hibernate:
- /* criteria query */ select
- this_.ID as ID1_1_0_,
- this_.name as name2_1_0_,
- this_.description as descript3_1_0_
- from
- t_supermarket this_
- Hibernate:
- /* load one-to-many com.shop.jn.entity.Supermarket.goods */ select
- goods0_.supermarketId as supermar8_1_1_,
- goods0_.ID as ID1_0_1_,
- goods0_.ID as ID1_0_0_,
- goods0_.name as name2_0_0_,
- goods0_.alias as alias3_0_0_,
- goods0_.buyDateTime as buyDateT4_0_0_,
- goods0_.latestModDateTime as latestMo5_0_0_,
- goods0_.price as price6_0_0_,
- goods0_.description as descript7_0_0_,
- goods0_.supermarketId as supermar8_0_0_
- from
- t_goods goods0_
- where
- goods0_.supermarketId=?
如果我设置lazy为true呢?
调用supermarket.getGoods().size()时就会报错:
- 10:31:14,097 WARN - Caught an exception while evaluating expression '0==goods.size' against value stack
- org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.shop.jn.entity.Supermarket.goods, could not initialize proxy - no Session
因为使用的是懒加载,查询supermarket时没有把goods查询出来。
inverse(可选 — 默认为 false)标记这个集合作为双向关联关系中的方向一端。因为这里是双向关联,所以设置inverse为true