天天看點

hibernate 映射-一對多雙向

項目名稱:shop_goods

spring :3.2.3.release

hibernate:4.2.2.final

struts2:2.3.4.1

使用xml配置,使用maven建構。

這裡涉及兩個實體類:商品,超市。因為要講解一對多的關系映射,是以假設商品和超市之間是多對一聯系。

一個超市有多個商品,一個商品隻屬于一個超市。

實體類代碼如下(省略setter,getter方法)

hibernate 映射-一對多雙向

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;  

}  

import java.util.list;  

 * entity:shop   超市 

public class supermarket  implements serializable{  

    private static final long serialversionuid = 6517742699077464699l;  

     * the name of the shop 

    private list<goods> goods;  

     * the sum of goods  

    private int goodsamount;  

    }  

 hibernate配置檔案如下

goods.hbm.xml(多的一方):

hibernate 映射-一對多雙向

<?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>  

        </property>  

        <property name="alias"  >  

            <column name="alias">  

                <comment>商品的别名</comment>  

        <property name="buydatetime">  

            <column name="buydatetime" >  

                <comment>購買時間</comment>  

        <property name="latestmoddatetime">  

            <column name="latestmoddatetime">  

                <comment>最後修改時間</comment>  

        <property name="price">  

            <column name="price">  

                <comment>商品價格</comment>  

        <property name="description">  

            <column name="description">  

                <comment>商品的具體資訊</comment>  

        <!-- 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>  

        </many-to-one>  

    </class>  

</hibernate-mapping>  

 supermarket.hbm.xml(一的一方):

hibernate 映射-一對多雙向

    <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" -->  

            <generator class="identity" />  

        <property name="name">  

                <comment>商店的名稱</comment>  

        <!--<property name="goodsamount"> <formula>(select count(*) from t_goods   

            g where g.supermarketid=id)</formula> </property> -->  

                <comment>商店的詳細資訊</comment>  

        <bag name="goods" lazy="false" fetch="subselect" inverse="true">  

            <key column="supermarketid"></key>  

            <one-to-many class="com.shop.jn.entity.goods" />  

        </bag>  

 主要對bag标簽進行詳細的說明

bag标簽中有如下屬性

lazy(可選--預設為 true)可以用來關閉延遲加載(false)

如果指定lazy為false,則在查詢supermarket(一的一方)時會把supermarket中的goods(多的一方)也查詢出來,查詢的的政策有三種:subselect,select,join

這裡使用的政策是fetch屬性指定的subselect,執行的sql語句如下:

hibernate 映射-一對多雙向

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_  

    /* 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_   

        t_goods goods0_   

    where  

        goods0_.supermarketid=?  

如果我設定lazy為true呢?

調用supermarket.getgoods().size()時就會報錯:

hibernate 映射-一對多雙向

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