深入浅出hibernate之PO,VO,load,get

  • Post author:
  • Post category:其他


今天老师重新详细讲解了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 语句.

转载于:https://www.cnblogs.com/sunwei2012/archive/2009/12/31/1637233.html