1

When used @Transactional annotation in a method and we do not modify the domain object, still a new reference of the new object is committed.

For example lets take a sample case:

Domain Object:

@Table(name = "SAMPLE_TABLE")
public class SampleTable{        
    @Column(name = "ID")
    String id;

    @Column(name = "FIRST_NAME")
    String firstName;

    @Column(name = "CITY")
    String city;

    @Column(name = "STREET_ADDRESS")
    private String streetAddress;
}

And I have a service method with @Transactional annotation but doesn't modify the domain object.

@Transactional
public void doNothing(String id) {
    SampleTable sampleTable = sampleTableRepository.findById(id);       
}

So, whenever doNothingmethod is executed, I see the domain object becomes dirty since a new reference with no change in data is committed.(Confirmed this using Hibernate Interception findDirty method). When I remove the @Transactional this(dirty object) doesn't happens.

Is this a normal behavior or a bug in Hibernate.

Arun
  • 1,176
  • 5
  • 20
  • 48
  • Can you add the code for `Model` too? I assume you haven't overridden the method `findById` on the spring repository. Can you confirm this? – Augusto Feb 15 '16 at 18:01
  • I removed the model class. It just had a generated String id. I now added id to the existing class. I have a method SampleTable findById(String id); in the interface SampleTableRepository which I have created. – Arun Feb 15 '16 at 18:03
  • I think it a read only issue: see [here](http://stackoverflow.com/questions/13539213/why-do-i-need-transaction-in-hibernate-for-read-only-operation) – hasnae Feb 15 '16 at 18:11
  • @hasnae: Can you elaborate? – Arun Feb 15 '16 at 18:13
  • It's not "NORMAL" behaviour by the JPA spec, and I wouldn't expect other implementations to do that. Nothing should be "dirty" there (as you say). – Neil Stockton Feb 15 '16 at 18:39
  • @NeilStockton: Can you give the link for the JPA spec where it is saying that it is normal. I am not able to find it out. – Arun Feb 15 '16 at 19:57

2 Answers2

0

There are lots of complicated configuration options for transactions in Spring. It's worth adding @ReadOnly to transactions that you are certain really are read-only.

Community
  • 1
  • 1
whistling_marmot
  • 3,561
  • 3
  • 25
  • 39
0

Hibernate apply a strategy ( inspection ) to detect dirty objects (for example If the object is still transient then it is always dirty.). So to avoid dirty check use the readonly annotation ( The point 5. from the post: Another thing when it comes to Hibernate, Spring sets the FlushMode to MANUAL in case of read-only transactions, which leads to other optimizations like no need for dirty checks.)

Community
  • 1
  • 1
hasnae
  • 2,137
  • 17
  • 21
  • The information is useful. But, my actual question is why is the object dirty when it is not modified by the method. – Arun Feb 15 '16 at 19:25