Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DTO entity mapping with hibernate @Version control

I am using @Version annotation to provide version control in hibernate. My question is regarding the proper mapping of data from DTO to Entity. What I feel is the right way is as follows but I want to know if there is a better way or this is how everybody does it.

  • call comes to my service
  • i load the entity to be updated (assume AddressEntity with version = 1)
  • i map the AddressDTO values to AE, including sub-collections if any
  • after all mapped, i detach the entity AE (only to be detached after Lazy sub collections mapped too)
  • now i map the version from DTO to AE (as hibernate does not allow to update version in managed entity)
  • now i call merge to update this detached AE entity

1) Is this the right way semantics and logic wise ?

2) (bit out of context) is there an overhead for hibernate to merge an object already in context and managed ie can i use merge for all updates safely irrespective or managed/unmanaged or Only merge+flush for unmanaged and flush for managed after updating some properties ?

like image 786
Ashish Thukral Avatar asked Dec 11 '25 08:12

Ashish Thukral


1 Answers

Let me try to answer your question stepwise:

  1. Suppose you have loaded an AddressEntity (having id=123 and version=1). Set the property values from AddressEntity to AddreeDto including the id and version values. Send the AddressDto to UI.
  2. Changes made to AddresDto. Call has come to your service. Create an instance of AddressEntity and set the values from AddressDto including the id and version values. This new AddressEntity has now turned into a detached instance, as it has a persistent identity, but its state is not guaranteed to be synchronized with database state.
  3. Hibernate lets you reuse this Addressentity instance in a new transaction by reassociating it with a new persistence manager.This detached instance can be reassociated with a new Session by calling update(). You don't need to load the entity again.The update() method forces an update to the persistent state of the object in the database.

    Set the addressEntity properties:

    addressEntity.setId(dto.getId()); addressEntity.setVersion(dto.getVersion());

    Attach addressEntity to a new session:

    Transaction tx = sessionTwo.beginTransaction(); sessionTwo.update(addressEntity);

    tx.commit(); sessionTwo.close();

  4. The session.update will execute an SQL similar to this:

    update ADDRESS_ENTITY set ... , VERSION=2 where ID=123 and VERSION=1

  5. If another application transaction would have updated the same ADDRESS_ENTITY since it was loaded, the VERSION column would not contain the value 1, and the row would not be updated, and you will receive a stale object state exception. You can catch the exception and inform the User about the stale data.

like image 62
Debojit Saikia Avatar answered Dec 13 '25 00:12

Debojit Saikia



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!