`
septem
  • 浏览: 53303 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate Session持久化方法实战

阅读更多
Hibernate Session中有一系列的持久化方法比如:save, update, saveOrUpdate, persist, merge, replicate等等,经常有人问起它们之间的细微差别,而Hibernate的官方文档并没有进行详细的说明,因此以几个测试用例验证它们的不同之外。文中所使用的持久化类以及配置请参考之前写的hibernate二级缓存

一、save, update, saveOrUpdate

这三个方法使用最为频繁,区别较直观,简单说一下

save:持久化对象,并根据ID生成策略分配ID

update(detachedInstance):根据detachedInstance的ID更新该对象,如果当前session中存在相同ID的persistent instance会抛异常

saveOrUpdate:根据对象ID的unsaved-value来决定是执行save还是update

代码:略

二、update, merge

merge(detachedInstance):merge方法会将detachedInstance的属性复制到相同ID的持久化对象,并返回该持久化对象。注意这里的detachedInstance本身并不会被持久化,继续保持游离状态,这是merge与update的最大区别

测试用例如下:
@Test
	public void test_update_merge(){
		Session session = sessionFactory.openSession();
		Author a1 = new Author();
		a1.setName("septem");
		session.save(a1);
		session.close();
		
		session = sessionFactory.openSession();
		a1.setName("septem_new");
		
		//Copy the state of a1 onto the persistent object a2
		Author a2 = (Author) session.merge(a1);
		//a1 doesn't become associated with the session
		assertFalse(session.contains(a1));
		
		assertEquals(a1.getName(), a2.getName());
		
		session.close();
	}


三、save, persist

persist与save不同的地方在于2点:
1.persist把对象进行持久化,但是不保证立刻生成ID,ID的生成可能被推迟到flush的时候

2.在transaction外部调用persist的时候并不触发sql Insert

测试用例如下:

@Test
	public void test_persist_outside_transaction(){
		Session session = sessionFactory.openSession();
		Author a1 = new Author();
		a1.setName("septem");
		//persist outside transaction
		session.persist(a1);
		//ID is NOT assigned
		assertNull(a1.getId());
		assertTrue(session.contains(a1));
		session.close();
		//hibernate doesn't execute INSERT statement
		assertNull(a1.getId());
	}


四、lock

lock(Object object, LockMode lockMode):lock方法根据LockMode获取相应的锁,并将对象持久化,它的主要作用是获取锁。

但是在实际测试的时候,发现如果对Author对象调用lock方法的时候会抛异常(org.hibernate.HibernateException: reassociated object has dirty collection reference),而在book对象上调用的时候则正常,猜测应该是author对象存在一对多的关系,包含了book集合,但具体原因还不清楚,有对hibernate熟悉的朋友请指点

测试用例如下:

@Test
	public void test_lock_author_throw_exception(){
		Session session = sessionFactory.openSession();
		Author a1 = new Author();
		a1.setName("septem");
		session.save(a1);
		session.close();
		
		session = sessionFactory.openSession();
		
		try {
			session.lock(a1, LockMode.NONE);
			fail("lock doesn't throw exception as expected");
		} catch (HibernateException e) {
			// org.hibernate.HibernateException: reassociated object has dirty collection reference
		}
		assertTrue(session.contains(a1));
		
		session.close();
	}
	
	@Test
	public void test_lock_book(){
		Session session = sessionFactory.openSession();
		Book book = new Book();
		book.setTitle("java");
		session.save(book);
		session.close();
		
		session = sessionFactory.openSession();
		
		session.lock(book, LockMode.NONE);
		// book is associated with the session	
		assertTrue(session.contains(book));
		
		session.close();
	}


五、replicate

replicate(Object object, ReplicationMode replicationMode):在ID是自动生成的情况下,save会持久化对象,并生动分配ID。而replicate同样是持久化对象,但它允许你指定ID。如果指定ID的纪录已经存在,它会根据参数ReplicationMode来决定是抛异常,还是覆盖原来的对象或者是直接忽略持久化操作

测试的时候,我指定了一个已经存在的ID进行replicate操作,ReplicationMode为ReplicationMode.EXCEPTION,实际的情况并没有抛出异常,而是直接生成是另外一个对象,ID为自动分配,相当于对transient instance调用save方法!google了一下,发现这个方法跟底层的数据与ID生成策略有关(参考这里),不同情况它的结果会不一样,所以在实践中还是应该慎用!

3
0
分享到:
评论

相关推荐

    Hibernate实战(第2版 中文高清版)

     第1章 理解对象/关系持久化   1.1 什么是持久化   1.1.1 关系数据库   1.1.2 理解SQL   1.1.3 在Java中使用SQL   1.1.4 面向对象应用程序中的持久化   1.2 范式不匹配   1.2.1 粒度问题   1.2.2 ...

    深入浅出Hibernate中文版 part1

    5.1 Hibernate持久化实现 5.2 Hibernate回调与拦截机制 5.3 Hibernate实用技术 第6章 Hibernate 实战——创建RedSaga论坛 6.1 目标 6.2 E-R建模还是对象建模 6.3 E-R建模及工具集 6.4 对象建模 6.5 项目的...

    深入浅出Hibernate中文版 part2

    5.1 Hibernate持久化实现 5.2 Hibernate回调与拦截机制 5.3 Hibernate实用技术 第6章 Hibernate 实战——创建RedSaga论坛 6.1 目标 6.2 E-R建模还是对象建模 6.3 E-R建模及工具集 6.4 对象建模 6.5 项目的...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    10.3.1 持久化上下文和持久化单元 382 10.3.2 实体类的要求 382 10.3.3 实体的状态 383 10.3.4 管理实体的方法 384 10.4 实体的基本映射387 10.4.1 映射实体类的属性 387 10.4.2 将实体映射到多个表 394 10.4.3 映射...

    JAVA WEB典型模块与项目实战大全

    7.5 指点迷津——session知识  7.6 统计在线人数功能  7.7 小结  第8章 网络购物车(jsp+servlet+javabean)  8.1 网络购物车原理  8.2 实现网络购物车功能  8.3 小结  第9章 搜索引擎(lucene+web ...

    Java Web程序设计教程

    第13章 spring与javaee持久化数据访问 260 13.1spring对dao模式的支持 260 13.1.1统一的数据访问异常 260 13.1.2通用的数据访问模板及抽象支持类 261 13.2spring的jdbc 262 13.2.1为什么需要jdbctemplate 262...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    第10章 邂逅数据库持久化利器 第11章 探秘数据库持久化利器 第12章 简化企业开发瑰宝之一 第13章 简化企业开发瑰宝之二 第14章 程序员的伴侣 第2篇 范例演练篇 第15章 学以致用 第16章 幕后英雄的用武之地 第17章 ...

    Java语言基础下载

    操纵持久化对象 698 选择继承关系的映射方式 699 映射多对一多态关联 702 内容总结 705 独立实践 705 第三十六章:HQL介绍 706 学习目标 706 HQL的出现 707 进入HQL世界 707 聚合 708 分组 709 在Java中使用HQL 709 ...

    springmybatis

    MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan ...

    深入浅出Struts2(附源码)

    作者处处从实战出发,在丰富的示例中直观地探讨了许多实用的技术,如数据类型转换、文件上传和下载、提高Struts 2应用的安全性、调试与性能分析、FreeMarker、Velocity、Ajax,等等。跟随作者一道深入Struts 2,聆听...

    深入浅出Struts 2 .pdf(原书扫描版) part 1

    作者处处从实战出发。在丰富的示例中直观地探讨了许多实用的技术。如数据类型转换、文件上传和下载、Struts2应用的安全性、调试与性能分析、FreeMarker、Velocily、Ajax,等等。跟随作者一道深入Struts2。聆听大量...

Global site tag (gtag.js) - Google Analytics