`
lchlrb
  • 浏览: 6430 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
最近访客 更多访客>>
社区版块
存档分类
最新评论

关于hibernate3 中bulk delete/update与缓存同步问题

阅读更多
   小弟最近刚学hibernate,看的是深入浅出hibernate一书。里面碰到一些关于缓存的问题。
建了个简单的表测试 User 里面的字段只有 id 和 name

其中操作User类中(OperatorUser类)有个删除User的方法和获取User的方法如下
//删除User
          
public void deleteUser(String id){
		Transaction tran = session.beginTransaction() ;
		String hql = "delete User where id=?" ;
		Query q = session.createQuery(hql) ;
		q.setString(0, id) ;
		
		q.executeUpdate() ;
		
		tran.commit() ;
	}

         //获取user
public User getUser(String id){
		Transaction tran = this.session.beginTransaction() ;
		User user = (User) this.session.load(User.class, id) ;
		tran.commit() ;
		
		return user ;
	}
         


写了个测试类Test
       
 OperatorUser op = new OperatorUser() ;
	User user=op.getUser("001") ;
	System.out.println(user.getName()) ;
		
	op.deleteUser("001") ;
		
	User user01= op.getUser("001") ;
	System.out.println(user01.getName()) ;


运行,没错,会打印出相同的姓名。因为当调用deleteUser()方法时,Hibernate的内部缓存和数据库不同步。但是当我注释掉
          
           //System.out.println(user.getName()) ;
          
           //op.deleteUser("001") ;

//User user01= op.getUser("001") ;
//System.out.println(user01.getName()) ;

再重新运行一次下面注释掉一些的代码-----意味着重新打开了一个session,而前面运行那次的session已经关闭,相对应前面的session的缓存也不存在了。
         OperatorUser op = new OperatorUser() ;
User user=op.getUser("001") ;--运行到此时,不会抛出异常,从二级缓存中取出的吗?        //System.out.println(user.getName()) ;---取消注释,运行到此时候,抛出异常,说没有相应的列          
         //op.deleteUser("001") ;

//User user01= op.getUser("001") ;
//System.out.println(user01.getName()) ;

可以,没错,不会抛出异常,但,加上System.out.println(user.getName());时,
却抛出异常,说数据库中没有相应的列!
    问题就在这:为什么调用op.getUser("001")不会抛出异常,为什么调用user.getName()却说没有相应的列!
两次运行,不同的session,内部缓存不同。但是二级缓存相同。也就是说二级缓存里应该有Id 为 001的User实体对象才是。但是为什么调用user.getName()时会抛出异常呢?

通过指点,再在网上查了下关于session.load方法的信息,的确是关于load方法延迟加载的问题,而和缓存没有多大关系,因为两次运行,无论是sessionfactory还是session,两次都不同。

关于session.load():
1. load方法会先从内部缓存和二级缓存中查找实体对象,看看缓存中是否存在该对象。session.get()方法也一样。
2. hibernate中的load方法的加载方式是延迟加载, 返回的是一个实体对象的代理实例,,此时的代理类实例是由运行时动态生成的类,该代理类实例包括原目标对象的所有属性和方法,该代理类实例的属性除了ID不为null外,所在属性为null值,当调用getXXX()方法时,才会真正地到数据库里获得属性值。所以第二次再执行时,会抛出异常!
分享到:
评论
3 楼 lchlrb 2008-09-02  
    恩,谢谢两位的指点,再在网上查了下关于session.load方法的信息,的确是关于load方法延迟加载的问题,而和缓存没有多大关系,因为两次运行,无论是sessionfactory还是session,两次都不同。

     关于session.load():
          1. load方法会先从内部缓存和二级缓存中查找实体对象,看看缓存中是否存在该对象。session.get()方法也一样。
          2. hibernate中的load方法的加载方式是延迟加载, 返回的是一个实体对象的代理实例,,此时的代理类实例是由运行时动态生成的类,该代理类实例包括原目标对象的所有属性和方法,该代理类实例的属性除了ID不为null外,所在属性为null值,当调用getXXX()方法时,才会真正地到数据库里获得属性值。所以第二次再执行时,会抛出异常!

     谢谢两位的指点。
2 楼 taupo 2008-09-02  
因为load方法是延时加载,你用get就会马上抛出异常了
1 楼 i5cn 2008-09-02  
你用的是延时加载,获取PO的时候用的是load()方法,Hibernate中对load()加载方式的处理是,认为"001"这个id对应的对象在数据库中是一定存在的,所以使用代理来延迟加载对象,也就是说当你第二次执行到
User user = op.getUser("001");
的时候,Hibernate并没有去数据库中去取得这个id为"001"的对象,可是第一次你执行测试代码的时候你已经把数据库里的数据删掉了啊,所以第二次再执行到
System.out.println(user.getName());
的时候,就要真正去数据库中取了,然后就会抛出没有相应的列的异常了。

数据库没数据是我估计的,说的不一定对。

相关推荐

    最全Hibernate 参考文档

    13.3. 大批量更新/删除(Bulk update/delete) 14. HQL: Hibernate查询语言 14.1. 大小写敏感性问题 14.2. from子句 14.3. 关联(Association)与连接(Join) 14.4. select子句 14.5. 聚集函数 14.6. 多态查询 14.7. ...

    hibernate立体结构文档

    3. 批量操作:使用bulk update和bulk delete提高效率。 总结,“hibernate3.0立体文档”中的32个示例覆盖了Hibernate的基础和进阶应用,包括配置、映射、CRUD操作、查询、关联关系、事务和性能调优等方面,为初学者...

    hibernate中文帮助文档

    2. 支持批量操作:通过BatchSize属性或HQL的BULK UPDATE和BULK DELETE实现批量处理。 3. 异步操作:通过Future和AsyncQuery接口进行异步查询,提高系统响应速度。 本中文参考文档详细介绍了Hibernate 3.2的各个方面...

    Hibernate3+中文参考文档

    13.3. 大批量更新/删除(Bulk update/delete) 14. HQL: Hibernate查询语言 14.1. 大小写敏感性问题 14.2. from子句 14.3. 关联(Association)与连接(Join) 14.4. select子句 14.5. 聚集函数 14.6. 多态查询 14.7. ...

    Hibernate方法总结

    在Java持久化框架Hibernate中,HibernateTemplate是一个便捷的工具类,它封装了常见的数据库操作,使得开发者能够更方便地与数据库交互。以下是对标题和描述中提到的HibernateTemplate方法的详细总结: A. `get` 和...

    Hibernate_api

    - Hibernate提供了批处理功能,如bulk update和bulk delete,优化大量数据的处理效率。 - 使用Session的flushMode设置控制何时将脏数据同步到数据库。 8. 链接其他技术: - Spring框架集成:Spring提供了对...

    公司内部hibernate知识培训

    3. 实体类与表映射:在Hibernate中,实体类代表数据库中的表,通过注解或者XML文件进行映射。例如,@Entity表示一个实体,@Table定义对应的数据库表名,@Id标识主键,@Column指定字段映射等。 4. Session与...

    hibernate3.04中文文档.chm

    14.3. 大批量更新/删除(Bulk update/delete) 15. HQL: Hibernate查询语言 15.1. 大小写敏感性问题 15.2. from子句 15.3. 关联(Association)与连接(Join) 15.4. select子句 15.5. 聚集函数 15.6. 多态查询 ...

    hibernate入门

    5. 批量操作:优化大量数据的插入、更新和删除,如bulk update和bulk delete。 **六、源码分析** 深入理解Hibernate的工作原理,可以查看其开源源码,研究Session、SessionFactory、Query等关键类的实现,以及如何...

    Hibernate教程

    14.3. 大批量更新/删除(Bulk update/delete) 15. HQL: Hibernate查询语言 15.1. 大小写敏感性问题 15.2. from子句 15.3. 关联(Association)与连接(Join) 15.4. select子句 15.5. 聚集函数 15.6. 多态查询 ...

    hibernate笔记

    Hibernate提供了批量插入、更新和删除的API,如Session的batch_size属性,以及bulk_update和bulk_delete方法,可以显著提升性能。 10. 异常体系: Hibernate有一套自己的异常体系,如HibernateException、...

    Hibernate3.2官方中文参考手册

    2. CRUD操作:Hibernate提供了增删改查的便捷接口,如Session的get()、load()、delete()、update()和flush()等。 五、查询语言(HQL) 1. HQL是Hibernate特有的面向对象的查询语言,类似于SQL但更贴近于Java对象。 ...

    hibernate-distribution-3.3.2.GA

    - CRUD操作:使用Session的save(), update(), delete()和load(), get()等方法实现对象的创建、更新、删除和查询。 - 查询:HQL和Criteria API提供灵活的查询方式,可以实现复杂的条件查询和聚合操作。 6. 性能...

    Hibernate 高级特性

    2. 批量操作:批量插入、更新和删除,例如使用bulk update和bulk delete语句,减少数据库交互次数,提升性能。 三、 绩效优化 1. 分页查询:通过设置FirstResult和MaxResults参数,实现分页查询,减少不必要的数据...

    hibernate 框架详解

    大批量更新/删除(Bulk update/delete) 15. HQL: Hibernate查询语言 15.1. 大小写敏感性问题 15.2. from子句 15.3. 关联(Association)与连接(Join) 15.4. select子句 15.5. 聚集函数 15.6. 多态查询 15.7...

    Hibernate泛型DAO及使用方法借鉴.pdf

    总结,泛型Hibernate DAO是企业级应用中常见的设计模式,它封装了数据库操作,使得业务逻辑层与数据访问层分离,提高了代码的可复用性和可测试性。在实际开发中,可以根据项目的具体需求,对这个基础实现进行扩展和...

    hibernateTemplate的常用方法

    - 注意:使用`bulkUpdate`时,会直接执行原生SQL,因此失去了Hibernate的一些特性(如缓存机制)。 #### 总结 `HibernateTemplate`提供了丰富的API来支持常见的数据库操作,使得开发者能够更高效地进行数据访问层...

    HibernateTemplate汇总

    HibernateTemplate 是 Spring 框架中的一個关键组件,用于简化 Hibernate 的使用,提供了許多实用的方法来进行数据库操作。在本文中,我们将对 HibernateTemplate 的主要方法进行总结和解释。 ...

    hibernate 常用方法介绍

    它首先检查缓存,如果缓存中没有结果,再查询数据库,如果数据库中也找不到,将返回null。 4. `get(Class entityClass, Serializable id)`:这个方法根据主键加载特定的持久化实例。它先检查ID是否大于0,然后尝试...

Global site tag (gtag.js) - Google Analytics