JPA @Version behaviour

Posted by Albert Kam on Stack Overflow See other posts from Stack Overflow or by Albert Kam
Published on 2011-03-10T10:48:33Z Indexed on 2011/03/11 8:10 UTC
Read the original article Hit count: 253

Filed under:
|
|

Hello, im using JPA2 with Hibernate 3.6.x

I have made a simple testing on the @Version.

Let's say we have 2 entities,

  1. Entity Team has a List of Player Entities, bidirectional relationship, lazy fetchtype, cascade-type All
  2. Both entities have @Version

And here are the scenarios :

  1. Whenever a modification is made to one of the team/player entity, the team/player's version will be increased when flushed/commited (version on the modified record is increased).

  2. Adding a new player entity to team's collection using persist, the entity the team's version will be assigned after persist (adding a new entity, that new entity will got it's version).

  3. Whenever an addition/modification/removal is made to one of the player entity, the team's version will be increased when flushed/commited. (add/modify/remove child record, parent's version got increased also)

I can understand the number 1 and 2, but the number 3, i dont understand, why the team's version got increased ?

And that makes me think of other questions :

  1. What if i got Parent <-> child <-> granchildren relation ship. Will an addition or modification on the grandchildren increase the version of child and parent ?
  2. In scenario number 2, how can i get the version on the team before it's commited, like perhaps by using flush ? Is it a recommended way to get the parent's version after we do something to the child[s] ?

Here's a code sample from my experiment, proving that when ReceivingGoodDetail is the owning side, and the version got increased in the ReceivingGood after flushing. Sorry that this use other entities, but ReceivingGood is like the Team, ReceivingGoodDetail is like the Player. 1 ReceivingGood/Team, many 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());
}

© Stack Overflow or respective owner

Related posts about hibernate

Related posts about jpa