Hibernate 的一些注意点

转载 2011年01月07日 14:59:00

1,org.hibernate.id.IdentifierGenerationException: this id generator generates long, integer, short or string,当用sequence作为主键的generator时,主键只能是long, integer, short or string. 当定义表的主键长于number(18)(18的时候是long)是,hibernate自动生成的代码会用BigDecimal对应,这时候不能用sequence generator.

当数据库字段类型定义为NUMBER(1)的时候,hibernate的mapping文件中会对应为boolean类型.

2 Hibernate中有两个极为相似的方法get()与load(),他们都可以通过指定的实体类与ID从数据库中读取数据,并返回对应的实例,但 Hibernate不会搞两个完全一样的方法的,它们间的不同在于:

a,hibernate中get方法和load方法的根本区别在于:如果找不到符合条件的纪录,get()方法将返回null.而load()将会报出ObjectNotFoundEcception.如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常,所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这个对象时。由于 session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理,实际使用数据时才查询二级缓存和数据库.所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。

b,load()方法可以返回实体的代理类实例,而get返回的可能是实体类,也可能是代理类.get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。

类LockMode定义了6种锁定模式.
(1)LockMode.NONE:默认模式,表示无需锁机制.如果缓存中存在持久化实例,直接使用缓存中的实例.当用session.lock方法的时候,不会执行SQL语句,只有当对被lock的对象作改变,会有update语句.
(2)LockMode.READ:共享锁.载入数据直接从数据库中读取.当用session.lock方法的时候,总会执行SQL Select语句.
(3)LockMode.UPGRADE:使用select……from……for update格式载入数据,并为数据加锁.若数据不支持select……from……for update格式,则使用LockMode.READ模式.
(4)LockMode.UPGRADE_NOWAIT:使用Oracle风格的SQL语句:select……from……for update nowait载入数据.获得锁后,该模式和LockMode.UPGRATE模式的语义相同.
(5)LockMode.WRITE:当Hibernate更新或插入数据时,自动设置LockMode.WRITE模式,该械只能由Hibernate内部使用.
(6)LockMode.FORCE:使用版本控制时,强制实现版本增强,语义和LockMode.UPGRADE相同.

3,如果多表关联在多方的配置文件中指定了property-ref="主表的字段",在做关联查询的时候会执行不必要的SQL语句(在每次取子表数据时,会反向的用SQL再去取主表的数据).

4,多表关联查询用session.createCriteria(XXX.class);可能会包含主表的重复记录,需要用过滤,如下:

            criteria.add(Restrictions.eq("mval","mastinfo1")).
            setFetchMode("ukdettbs", FetchMode.EAGER); //execute 5 SQL select        
            List list = criteria.list();
            Set set = new HashSet(list);

5,Hibernate 对数据库的操作是更具当前Object处于的状态,从而将Object的值插入或者更新到数据库中.如果在混合使用SQL和HQL,对象值的改变操作时,SQL和HQL对数据的改变不会自动反映到对象上面,如果session在某个SQL或者HQL的update之后,又因为Object的值的改变而执行了另外一个update,SQL或者HQL的update会丢失.如下:

在同一个session中(HQL)的例子,对val的更新会丢失:

            tx = sessionFactory.getCurrentSession().beginTransaction();

            Hbtest tbo = new Hbtest();
            tbo.setId(id);
            sessionFactory.getCurrentSession().save(tbo);
           
            sessionFactory.getCurrentSession().createQuery("UPDATE com.test.hb.Hbtest ht SET ht.val=? WHERE ht.id=?")
            .setString(0, "val")
            .setInteger(1, id).executeUpdate();
           
            tbo.setVal2("val2");//由于val的值并没有反映到tbo对象上,val的值会丢失
           
            tx.commit();

在不同session中(SQL)的例子,对val的更新会丢失:

            tx = sessionFactory.getCurrentSession().beginTransaction();

            Hbtest tbo = new Hbtest();
            tbo.setId(id);
            sessionFactory.getCurrentSession().save(tbo);
            tx.commit();

            tx = sessionFactory.getCurrentSession().beginTransaction();

            sessionFactory.getCurrentSession().createSQLQuery("UPDATE HBTEST SET VAL=? WHERE ID=?")
            .setString(0, "val")
            .setInteger(1, id).executeUpdate();
            tx.commit();

            tx = sessionFactory.getCurrentSession().beginTransaction();
            tbo.setVal2("val2");//由于val的值并没有反映到tbo对象上,val的值会丢失
            sessionFactory.getCurrentSession().update(tbo);
            tx.commit();

6,Hibernate在做级联删除的时候,如果主表方的inverse为false,会先将子表的外键设为null,然后再删除,如果外键设了not null限制,会有异常发生.如果inverse为true,则不会有将子表的外键设为null的步骤.

在inverse=false的时候,在删除主表对应的Object的时候,如果没有将子表对应的object加到主表对应的object的set里,只会将子表的外键设为null.

如果inverse=true,在删除主表对应的Object的时候,如果没有将子表对应的object加到主表对应的object的set里,只会删除主表,引发数据库异常.

7,cascade的delete 和delete-orphan的区别,在把一个主表对应的记录load或者get到session后,如果将子表的记录从主表对应对象的set里remove掉,delete-orphan会将子表记录delete掉.而cascade设为delete时,如果inverse为false,会将子表的外键设为null,如果inverse设为true,不会对子表进行操作.

8,对native SQL query进行cache的时候遇到的java.lang.ClassCastException: XXXX at org.hibernate.cache.StandardQueryCache.put(StandardQueryCache.java:83) 问题:SQLQuery.addScalar来解决.

Query q1 = session.createSQLQuery("select val from Hbtest h where h.id<3");

q1.setCacheable(true);
((SQLQuery)q1).addScalar("val", Hibernate.STRING);

9,对于一个非active的session进行commit和rollback会有异常,所以在rollback的时候最好进行如下判断:

if (null != tx && tx.isActive())  {
     tx.rollback();
}

10,一个表可以对应多个class:

    <class name="com.test.hb.Hbtest" table="HBTEST">

    <class name="com.test.hb.Hbtest1" table="HBTEST">

11,如果一条数据库的数据被两个线程并发load然后做修改,会出现'丢失更新'


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kkdelta/archi

Hibernate中update方法的注意点

Hibernate 中如果直接使用 Session.update(Object o); 会把这个表中的所有字段更新一遍。 public class Teacher...

hibernate--MYSQL建表时type=InnoDB和Engine=InnoDB注意点

hibernate初学在配置好一切之后,运行然后报错,接下来问度娘,最后解决。。。 首先看报错[org.hibernate.engine.jdbc.env.internal.JdbcEnvironm...

hibernat使用junit测试类测试hibernate的各种方法说明及注意要点

hibernat使用junit测试类测试hibernate的各种方法说明及注意要点

hibernate原生sql查询和hql查询的注意点

package com.xiangshuai.test;   import java.util.List;   import org.hibernate.Query; import org....

Hibernate乐观锁的实现原理剖析与使用乐观锁时的注意点

Hibernate支持乐观锁。当多个事务同时对数据库表中的同一条数据操作时,如果没有加锁机制的话,就会产生脏数据(duty data)。Hibernate有2种机制可以解决这个问题:乐观锁和悲观锁。这...

hibernate 的hql查询语句中使用fetch的注意点

hibernate 的hql中使用fetch 可以取消lazy load,有效减少发出的sql查询语句(多sql语句意味着多次访问数据库,加大连接次数,降低使用效率)。提高数据库的访问效率。但是在使用...

hibernate配置文件注意点

一主配置文件注意点(xx.cfg.xml) 1.表的生成策略(hibernate.cfg.xml)   update create-drop (测试使用): 在Hibernate启动(ses...

Hibernate 3 介绍以及注意点

一.介绍          1. Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了轻量级的对象封装,使 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。它不仅...

hibernate 事务管理注意事项

  • 2016年06月01日 14:57
  • 73KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Hibernate 的一些注意点
举报原因:
原因补充:

(最多只允许输入30个字)