首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Hibernate Session持久化步骤实战

2012-10-06 
Hibernate Session持久化方法实战Hibernate Session中有一系列的持久化方法比如:save, update, saveOrUpda

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的最大区别

测试用例如下:

@Testpublic 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 a2Author a2 = (Author) session.merge(a1);//a1 doesn't become associated with the sessionassertFalse(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

测试用例如下:

@Testpublic void test_persist_outside_transaction(){Session session = sessionFactory.openSession();Author a1 = new Author();a1.setName("septem");//persist outside transactionsession.persist(a1);//ID is NOT assignedassertNull(a1.getId());assertTrue(session.contains(a1));session.close();//hibernate doesn't execute INSERT statementassertNull(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熟悉的朋友请指点

测试用例如下:

@Testpublic 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();}@Testpublic 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 sessionassertTrue(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生成策略有关(参考这里),不同情况它的结果会不一样,所以在实践中还是应该慎用!

热点排行