我在Hibernate 3.6.x中使用JPA2
我对@Version进行了简单测试。
假设我们有2个实体,
这是场景:
每当对团队/球员实体之一进行修改时,刷新/提交时,团队/球员的版本就会增加(修改后的记录的版本会增加)。
使用persist将新的球员实体添加到团队的集合中,将在persist之后分配团队版本的实体(添加新实体,该新实体将获取其版本)。
每当对一个玩家实体进行添加/修改/删除时,刷新/提交后团队的版本就会增加。(添加/修改/删除孩子的记录,父母的版本也增加了)
我可以理解数字1和2,但是我不能理解数字3,为什么团队的版本增加了?
这让我想到了其他问题:
这是来自我的实验的代码示例,证明当ReceivingGoodDetail是拥有方时,刷新后该版本在ReceivingGood中得到了增加。抱歉,这使用其他实体,但是ReceivingGood像Team,ReceivingGoodDetail像Player。1个ReceivevingGood / Team,很多ReceivingGoodDetail / Player。
/* Hibernate: select receivingg0_.id as id9_14_, receivingg0_.creationDate as creation2_9_14_, .. too long Hibernate: select product0_.id as id0_4_, product0_.creationDate as creation2_0_4_, .. too long before persisting the new detail, version of header is : 14 persisting the detail 1c9f81e1-8a49-4189-83f5-4484508e71a7 printing the size of the header : Hibernate: select details0_.receivinggood_id as receivi13_9_8_, details0_.id as id8_, details0_.id as id10_7_, .. too long 7 after persisting the new detail, version of header is : 14 Hibernate: insert into ReceivingGoodDetail (creationDate, modificationDate, usercreate_id, usermodify_id, version, buyQuantity, buyUnit, internalQuantity, internalUnit, product_id, receivinggood_id, supplierLotNumber, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: update ReceivingGood set creationDate=?, modificationDate=?, usercreate_id=?, usermodify_id=?, version=?, purchaseorder_id=?, supplier_id=?, transactionDate=?, transactionNumber=?, transactionType=?, transactionYearMonth=?, warehouse_id=? where id=? and version=? after flushing, version of header is now : 15 */ public void addDetailWithoutTouchingCollection() { String headerId = "3b373f6a-9cd1-4c9c-9d46-240de37f6b0f"; ReceivingGood receivingGood = em.find(ReceivingGood.class, headerId); // create a new detail ReceivingGoodDetail receivingGoodDetailCumi = new ReceivingGoodDetail(); receivingGoodDetailCumi.setBuyUnit("Drum"); receivingGoodDetailCumi.setBuyQuantity(1L); receivingGoodDetailCumi.setInternalUnit("Liter"); receivingGoodDetailCumi.setInternalQuantity(10L); receivingGoodDetailCumi.setProduct(getProduct("b3e83b2c-d27b-4572-bf8d-ac32f6de5eaa")); receivingGoodDetailCumi.setSupplierLotNumber("Supplier Lot 1"); decorateEntity(receivingGoodDetailCumi, getUser("3978fee3-9690-4377-84bd-9fb05928a6fc")); receivingGoodDetailCumi.setReceivingGood(receivingGood); System.out.println("before persisting the new detail, version of header is : " + receivingGood.getVersion()); // persist it System.out.println("persisting the detail " + receivingGoodDetailCumi.getId()); em.persist(receivingGoodDetailCumi); System.out.println("printing the size of the header : "); System.out.println(receivingGood.getDetails().size()); System.out.println("after persisting the new detail, version of header is : " + receivingGood.getVersion()); em.flush(); System.out.println("after flushing, version of header is now : " + receivingGood.getVersion()); }
看起来像是Hibernate中的错误。
JPA规范说:
所有非关系字段和属性以及实体拥有的所有关系都包含在版本检查中
但是,Hibernate还会在更改非所有关系属性后增加版本(例如,EclipseLink不会这样做)。可以通过@OptimisticLock(exclude = true)在属性上设置来禁用此行为。
@OptimisticLock(exclude = true)
请注意,它仅适用于关系属性本身的更改,不适用于引用对象状态的更改,因此不会由于父级集合的更改而更改父级的版本。