Hibernate基于配置文件(四)evict()与merge()的使用
?
evict()与merge()都用于解决:
内存中存在2个id相同的对象,session发现对象不唯一而抛出异常。
?
package org.leadfar.hibernate.model;import java.util.Date;import junit.framework.TestCase;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;public class UserTest03 extends TestCase {public void testUser_01() throws Exception {//默认读取类路径根目录下的hibernate.cfg.xml配置文件Configuration cfg = new Configuration().configure();//创建SessionFactorySessionFactory sfactory = cfg.buildSessionFactory();//创建Hibernate SessionSession session = sfactory.openSession();//创建实体对象User user = new User();//此时User对象处于Transient(瞬时)状态user.setName("张三");user.setAge(20);user.setSex(false);user.setBirthday(new Date());user.setMoney(99999.99);user.setId(109);try {//开启事务session.beginTransaction();User dbUser = (User)session.get(User.class, 109);Date oldbirthday = dbUser.getBirthday();//session.update(user):发生异常。//具有相同标识符的不同对象与同一个session相关联,引发异常NonUniqueObjectException//org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.leadfar.hibernate.model.User#109]session.update(user);//update离线对象---当前session绑定的对象是dbUser,但是更新的是user对象(内存中存在两个对象与数据库中同一条记录(id=109)相关联)user.setName("手机");user.setBirthday(oldbirthday);//提交事务session.getTransaction().commit();} catch(Exception e) {e.printStackTrace();//出现异常,回滚事务session.getTransaction().rollback();} finally {//关闭sessionsession.close();//session关闭之后,user对象处于离线Detached状态}}public void testUser_02() throws Exception {//默认读取类路径根目录下的hibernate.cfg.xml配置文件Configuration cfg = new Configuration().configure();//创建SessionFactorySessionFactory sfactory = cfg.buildSessionFactory();//创建Hibernate SessionSession session = sfactory.openSession();//创建实体对象User user = new User();//此时User对象处于Transient(瞬时)状态user.setName("张三");user.setAge(20);user.setSex(false);user.setMoney(99999.99);user.setId(109);try {//开启事务session.beginTransaction();User dbUser = (User)session.get(User.class, 109);Date oldbirthday = dbUser.getBirthday();//获取以前对象的birthday//切断与session的连接,释放sessionsession.evict(dbUser);//update离线对象,与session进行关联session.update(user);user.setName("手机");user.setBirthday(oldbirthday);//设置以前对象的birthday到新的对象中(保证birthday不变)//提交事务session.getTransaction().commit();} catch(Exception e) {e.printStackTrace();//出现异常,回滚事务session.getTransaction().rollback();} finally {//关闭sessionsession.close();//session关闭之后,user对象处于离线Detached状态}}//merge解决了两个对象关联一个session的问题public void testUser_merge() throws Exception {//默认读取类路径根目录下的hibernate.cfg.xml配置文件Configuration cfg = new Configuration().configure();//创建SessionFactorySessionFactory sfactory = cfg.buildSessionFactory();//创建Hibernate SessionSession session = sfactory.openSession();//创建实体对象User user = new User();//此时User对象处于Transient(瞬时)状态user.setName("美女2号线");user.setAge(20);user.setSex(false);user.setMoney(88.99);user.setId(109);//带更新的记录主键为109try {//开启事务session.beginTransaction();//dbUser与session关联User dbUser = (User)session.get(User.class, 109);user.setBirthday(dbUser.getBirthday());//设置以前对象的birthday到新的对象中(保证birthday不变)//merge--不用evict(驱逐)其它对象释放session//相当于把user对象的值拷贝到dbUser持久化对象中//由于没有调用update方法,所以user对象是处于瞬时状态的!//session关联的对象是dbUser,而user对象只是一个瞬时状态的对象session.merge(user);//提交事务session.getTransaction().commit();} catch(Exception e) {e.printStackTrace();//出现异常,回滚事务session.getTransaction().rollback();} finally {//关闭sessionsession.close();//session关闭之后,user对象处于离线Detached状态}}}
?