persist()方法不支持detached对象
同一事务中的操作:
不同事务中的操作:
结论:
对于Many2One One2Many里,对象里包含另一个对象的属性的情况
persist()限制较大,这"另一个对象"必须和当前对象在同一事务中,而且不能符合detached第二种形式(即id不能和数据库中有匹配,即必须是一个新对象)
既然persist()这么多限制,为什么很多场合还要用它而不是save()?
persist() also guarantees that it will not execute an INSERT statement if it is
called outside of transaction boundaries. This is useful in long-running conversations
with an extended Session/persistence context.A method like persist() is required.
persist()保证当它在一个transaction外部被调用的时候并不触发一个Sql Insert,这个功能是很有用的,
当我们通过继承Session/persistence context来封装一个长会话流程的时候,一个persist这样的函数是需要的。
比如一个长会话长事务,有可能触发事务的timeout(通常设为几十秒),这样save()很可能发生前事务已经结束(假设没设事务timeout 回滚的话),而这时save()仍然能执行,而这时persist()就无法执行,相对更安全
- 不管是detached形式一(session close造成),还是detached形式二(new对象 ,setId造成),
- 不管是在同一事务中(显然同一事务,只支持形式二),还是不同事务中(不同事务支持形式一和二)
同一事务中的操作:
1.Many对象和One对象操作在同一事务中时, One 对象为持久化对象, Many对象可正常通过persist()存储入库 mysql> select * from DvdTable1; +----+---------------------+-------------+------------+-------------+-------+------------+----------------+ | id | datetime | 13 | 2010-06-11 21:43:28 | no +----+---------------------+-------------+------------+-------------+-------+------------+----------------+ 11 rows in set (0.00 sec) |
2.Many对象和One对象操作在同一事务中时, One 对象为Transicent对象 Many对象可正常通过persist()存储入库,(同时One对象存储入库) mysql> select * from DvdTable1; +----+---------------------+-------------+------------+-------------+-------+------------+----------------+ | id | datetime | 15 | 2010-06-11 21:49:39 | no +----+---------------------+-------------+------------+-------------+-------+------------+----------------+ 13 rows in set (0.01 sec) mysql> select * from QualityType; +----+---------------+ | id | name +----+---------------+ | 18 | new1 +----+---------------+ 17 rows in set (0.00 sec) mysql> select * from DvdType; +----+------------+ | id | name +----+------------+ | 18 | new1 +----+------------+ 17 rows in set (0.00 sec) |
3.Many对象和One对象操作在同一事务中时, One 对象为new对象,但有转成persist对象的资格(其id值对应库表中的存在id),即其符合第二种detached态,它不是trancient 态. Many对象通过persist()存储入库时,抛出detached entity passed to persist异常 org.hibernate.PersistentObjectExceptio |
不同事务中的操作:
4.Many对象和One对象操作在不同事务中时, One 对象为Trancient对象 Many对象可通过persist()存储入库 mysql> select * from DvdTable1; +----+---------------------+-------------+------------+-------------+-------+------------+----------------+ | id | datetime | 16 | 2010-06-11 22:07:09 | no +----+---------------------+-------------+------------+-------------+-------+------------+----------------+ 14 rows in set (0.00 sec) mysql> select * from DvdType; | 19 | typetemp 6 | mysql> select * from QualityType; | 19 | qualitytemp 6 | |
5.Many对象和One对象操作在不同事务中时, One 对象为Persist对象转为detected对象(事务结束) Many对象通过persist()存储入库时,抛出detached entity passed to persist异常 org.hibernate.PersistentObjectExceptio |
6.Many对象和One对象操作在不同事务中时, One 对象为new对象,但有转成persist对象的资格(其id值对应库表中的存在id),即其符合第二种detached态,它不是trancient 态. Many对象通过persist()存储入库时,抛出detached entity passed to persist异常 org.hibernate.PersistentObjectExceptio |
结论:
对于Many2One One2Many里,对象里包含另一个对象的属性的情况
persist()限制较大,这"另一个对象"必须和当前对象在同一事务中,而且不能符合detached第二种形式(即id不能和数据库中有匹配,即必须是一个新对象)
既然persist()这么多限制,为什么很多场合还要用它而不是save()?
- 1.persist() 方法更标准,是JPA的标准CRUD方法,可移植性高
- 2.persist()在数据安全性上更可靠
persist() also guarantees that it will not execute an INSERT statement if it is
called outside of transaction boundaries. This is useful in long-running conversations
with an extended Session/persistence context.A method like persist() is required.
persist()保证当它在一个transaction外部被调用的时候并不触发一个Sql Insert,这个功能是很有用的,
当我们通过继承Session/persistence context来封装一个长会话流程的时候,一个persist这样的函数是需要的。
比如一个长会话长事务,有可能触发事务的timeout(通常设为几十秒),这样save()很可能发生前事务已经结束(假设没设事务timeout 回滚的话),而这时save()仍然能执行,而这时persist()就无法执行,相对更安全