Programmers

导航

hibernate 关联

额外,get 和load的区别

get先从缓存中查询是否有,有侧返回,不有则马上SELECT 数据库,如果数据库不存在对应的记录,则返回NULL

load也是先从缓存,有则返回,不有则看算了,如果有访问对象,再SELECT 数据库,如果不存在,则 异常:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.test.Person#4] (lazy加载,都会有这样Objec.....这样的异常)

一般我们不什么使用load方法.

 

one-to-one:

人表

 

护照表

基于主键单向的主到从表:

person.hbm.xml

        <id name="id" type="java.lang.Integer">

            <column name="id" />

            <generator class="native"/>

        </id>

..........................别的略

        <one-to-one name="passport" class="com.test.Passport" />

    </class>

passport.hbm.xml

      ...............

             <id name="id" type="java.lang.Integer" column="id">

           <generator class="foreign">

              <param name="property">person</param>  ----这里是从表基于主键关联的写法 , 也可以写成和上面的一样的映射

           </generator>

       </id>

...............

 Person p = (Person) session.get(Person.class, 1);

生成

Hibernate:
    select person0_.id as id1_1_, person0_.name as name1_1_, person0_.age as age1_1_, passport1_.id as id0_0_, passport1_.num as num0_0_
    from test.dbo.person person0_
    left outer join
    test.dbo.passport passport1_   on person0_.id=passport1_.id
    where
    person0_.id=?

说明再ono-to-one 的关联中,它并没有懒惰加载,而是直接的加载。

原因是:<one-to-one name="passport" class="com.test.Passport"  constrained="true"/>,如果加上,表示给对于告诉HBM, 我和Passport之间是有一定的关系约束的,比如

我的主是它的外键,只有这样,才能有懒惰加载的可能,在需要的passport时候,HBN通过这个关系的约束来select passport,当然,前提lazy != false,并且fetch != join ,这个时候,HBM进行懒惰:   select person0_.id as id1_0_, person0_.name as name1_0_,  person0_.age as age1_0_
    from   test.dbo.person person0_
    where    person0_.id=?

假如没有constrained="true" 那么,HBN,它在select 人的时候,它发现人的护照没有在人的表中,那么它会人的ID join 护照的ID,查询护照并且放到字段中,假如声明了constrained=true,的限制,那么,HBN 将会知道,这是一个有关系的关联,并且在lazy默认proxy的情况下和fetch = select,它采用了懒惰加载。(如果fetch = join,无论如何,都中直接加载,即便是lazy="proxy",或者cons...=true, 他们此时都无效,如果lazy=false, 那么,cons....无效,HBN根绝给定fetch进行立即加载)

当在级联操作中,有con..=true限制 的时候,并且lazy加载,delete前,HBN先select 从表(护照),如果找不到(因为是lazy加载,导致obj...异常),说明都还不过lazy加载这个关,如果找到然后删除它,假如不是采用lazy加载,而是join / select 加载时候,delete前并不实行select,没有必要,因为是立即加载的,但是假如说在delete时候如果找不到passport,那么必须丢出 attempt to create delete event with null entity,首先是因为,在join/select 立即加载的时候,person 的passport已经从数据库select 出来,con..=true对于HBN来说,person 表的数据是一一对应的,它不允许你找不到的现象,因为有constrained的限制,它是应该存在的.如果不存在,则异常。

当con..=false或者无限制,没有异常产生,有则删,无则过。因为HBN并不去关心或者说限制passport是否有一个数据对应于person.(是立即加载的,delete前无select,没有objectNotFo...的异常),

可以见,Constrained的限制,对级联delete是有影响的。

而对于save没什么可说的,如果是true,则两边数据一定要有11对应,update ,也没有什么可说的需要11对应,假如你想通过主对象导航到从对象,最多你会出现一个NollPointE..。

........更新中..................

 

posted on 2009-04-12 02:46  elan  阅读(162)  评论(0)    收藏  举报