zoukankan      html  css  js  c++  java
  • 深入浅出hibernate之PO,VO,load,get

    今天老师重新详细讲解了hibernate 里的POVO.

          最开始理解的POVO,感觉就是通过SAVE()方法,将OBJ 持久化到数据库.如果要UPDATE,只要将oBJ 里属性SET一个新值,然后执行下UPDATE就好(这是种错误的概念),因为那时还没怎么接触POVO,一开始看到这个已经感到很强大了,马上就在脑子中记住了POVO.
          本以为在项目中可以得心应手的利用这个好处,结果错误的理解让我出了很多异常:
          a different object with the same identifier value was already associated with the session;
          上面就是其中一个,原因是对于POVO的理解错误,引起的,先看下面的一段代码:
            Cat princess = new Cat();//新建一个Cat对象
      princess.setId("402881830c2cf0f3010c2cf0f8b40001");//将对象set一个数据库中已存在的ID
      princess.setName("Princess");
      princess.setSex('F');
      princess.setWeight(18.8f);
      
      Cat princess2 = new Cat();//又新建一个Cat对象
      princess2.setId("402881830c2cf0f3010c2cf0f8b40001");//同时将这个对象也set相同的ID
      princess2.setName("Princess");
      princess2.setSex('F');
      princess2.setWeight(19.8f);
      
      Session session = HibernateSessionFactory.currentSession();//好戏出场了,我们先current a Session
      Transaction tx = session.beginTransaction();//开始事物(Transaction到底是什么也不太懂,我只知道它可以将缓存中数据写入数据库)
    //  Cat c = (Cat)session.load(Cat.class, "402881830c2cf0f3010c2cf0f8b40001");
    //  c.setWeight(20.3f);
      session.saveOrUpdate(princess);//此时我们用session保存了princess,这之后的princess应该是持久化了,成了PO
      session.saveOrUpdate(princess2);//如果按我一开始的理解,此时princess2应该也是可以持久化的(看上面兰色部分),因为princess2只是将princess更新了而已(这是致命的错误).
      tx.commit();
      
      HibernateSessionFactory.closeSession();
      
       执行的结果总是那么讽刺, a different object with the same identifier value was already associated with the session
       遇到了问题,总是最让人兴奋与无奈的时候.还是来看看为什么出错吧:
      首先来讲讲POVO,PO又名persistence object,持久化对象,是指在对象通过save(),update(),load(),get();后,在session的Entity map实体容器里将持久话的对象add进去,也就是说,在我session.saveOrUpdate(princess);时,实体容器里已经将key和对象加入了.因为map是通过不同key来加OBJ的,而在hibernate里ID是唯一标识,使用ID来当做key是最好不过的了.因此Session 的实体容器只能加入一个id的对象.当session.saveOrUpdate(princess2);的时候,session准备把princess2也add到entityMap里时,由于相同的id,也就是key,它就报异常了a different object with the same identifier ..恭喜中标.
     
      也就是说PO是在session 的实体容器里可引用的对象,当我要更新PO时,可以set一个属性值,然后只要tx.commit();动作,就可以更新了(让我个人感到非常惊讶的地方).
      除了save();之外,同样通过load,update,get也可以获得PO.不过load和get有一少许区别(在使用的版本3.0中),get(id)就直接把DO获得(马上执行select操作),而load则不同,它会先对要load的ID做个标记,当要使用这个导出的对象时,它再执行.用上面的例子:
     
        Cat c = (Cat)session.load(Cat.class, "402881830c2cf0f3010c2cf0f8b40001");//此时只是做标记
        c.setWeight(20.3f);//这个时候才真正的执行了select 语句.
  • 相关阅读:
    面试2
    面试总结
    谈谈扫码支付的实现流程
    从产品分类、模块功能和业务流程,了解支付产品服务的设计
    【提现】的业务流程
    APP测试点归纳
    安全测试的思路
    一 大型网站架构演化(大型网站技术架构原理)
    Tomcat服务器原理详解
    Tomcat目录结构详解
  • 原文地址:https://www.cnblogs.com/sunwei2012/p/1637233.html
Copyright © 2011-2022 走看看