Hibernate基于配置文件(4)evict()与merge()的使用
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(); //创建SessionFactory SessionFactory sfactory = cfg.buildSessionFactory(); //创建Hibernate Session Session 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 { //关闭session session.close();//session关闭之后,user对象处于离线Detached状态 } } public void testUser_02() throws Exception { //默认读取类路径根目录下的hibernate.cfg.xml配置文件 Configuration cfg = new Configuration().configure(); //创建SessionFactory SessionFactory sfactory = cfg.buildSessionFactory(); //创建Hibernate Session Session 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的连接,释放session session.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 { //关闭session session.close();//session关闭之后,user对象处于离线Detached状态 } } //merge解决了两个对象关联一个session的问题 public void testUser_merge() throws Exception { //默认读取类路径根目录下的hibernate.cfg.xml配置文件 Configuration cfg = new Configuration().configure(); //创建SessionFactory SessionFactory sfactory = cfg.buildSessionFactory(); //创建Hibernate Session Session 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);//带更新的记录主键为109 try { //开启事务 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 { //关闭session session.close();//session关闭之后,user对象处于离线Detached状态 } } }