[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-2955) Unnecessary version updates in two cases.

Dmitry Katsubo (JIRA) noreply at atlassian.com
Tue Sep 6 10:22:03 EDT 2011


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2955?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43459#comment-43459 ] 

Dmitry Katsubo commented on HHH-2955:
-------------------------------------

I have the same situation as is described in first case:

When I persist the entity _IndexedDocument_ (that has many-to-many association with _Classification_), Hibernate also issues the update for the entity at the end, which I think is useless (as the entity has just been created in this transaction and is not visible outside it). Hibernate actions are logical when looking at log, but I hope this can be optimized.

{code}
[org.hibernate.persister.entity.AbstractEntityPersister] Inserting entity: org.mycompany.common.IndexedDocument (native id)
[org.hibernate.persister.entity.AbstractEntityPersister] Version: 0
[org.hibernate.SQL] insert into document (id, version, country_code, document_number, kind_code, creation_date, number_of_texts, number_of_images) values (default, ?, ?, ?, ?, ?, ?, ?)
[org.hibernate.persister.entity.AbstractEntityPersister] Dehydrating entity: [org.mycompany.common.IndexedDocument#<null>]
[org.hibernate.id.IdentifierGeneratorHelper] Natively generated identity: 0
[org.hibernate.engine.Cascade] processing cascade ACTION_PERSIST for: org.mycompany.common.IndexedDocument
[org.hibernate.engine.Cascade] cascade ACTION_PERSIST for collection: org.mycompany.common.IndexedDocument.classifications
[org.hibernate.event.def.AbstractSaveEventListener] transient instance of: org.mycompany.common.Classification
[org.hibernate.event.def.AbstractSaveEventListener] saving [org.mycompany.common.Classification#<null>]
[org.hibernate.event.def.AbstractSaveEventListener] executing insertions
[org.hibernate.event.def.AbstractSaveEventListener] executing identity-insert immediately
[org.hibernate.persister.entity.AbstractEntityPersister] Inserting entity: org.mycompany.common.Classification (native id)
[org.hibernate.SQL] insert into classification (id, code, type) values (default, ?, ?)
[org.hibernate.persister.entity.AbstractEntityPersister] Dehydrating entity: [org.mycompany.common.Classification#<null>]
[org.hibernate.persister.entity.AbstractEntityPersister] org.mycompany.common.IndexedDocument.classifications is dirty
[org.hibernate.persister.entity.AbstractEntityPersister] Updating entity: [org.mycompany.common.IndexedDocument#0]
[org.hibernate.persister.entity.AbstractEntityPersister] Existing version: 0 -> New version: 1
[org.hibernate.SQL] update document set version=?, number_of_texts=?, number_of_images=? where id=? and version=?
{code}

Hibernate v3.6.5.

> Unnecessary version updates in two cases.
> -----------------------------------------
>
>                 Key: HHH-2955
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2955
>             Project: Hibernate Core
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.2.5
>         Environment: JDK 5.0
>            Reporter: Sławomir Wojtasiak
>         Attachments: HibernateTest.zip
>
>
> I found two situations where hibernate generates unnecessary version updates. Let's illustrate it with a simple example: 
> Session session = SessionFactory.getSession();
> Transaction transaction = session.getTransaction();
> transaction.begin();
> 	
> Article a = new Article();
> a.setName( "atricle" );
> *********************************************
> *** Quantity is the owner of the relation ***
> *********************************************
> Quantity q = new Quantity();
> q.setName( "quantity" );
> q.setArticle( a );
> 		
> a.getQuantities().add( q );
> 	
> session.persist( a );	
> session.flush();
> ***** Hibernate generates following SQLs *****
> Hibernate: select nextval ('hibernate_sequence')
> Hibernate: select nextval ('hibernate_sequence')
> Hibernate: insert into Article (name, version, id) values (?, ?, ?)
> Hibernate: insert into Quantity (article_id, name, version, id) values (?, ?, ?, ?)
> **********************************************
> 		
> a.getQuantities().clear();
> 		
> session.flush();
> 		
> *** Hibernate generates following SQLs ***
> Hibernate: update Article set name=?, version=? where id=? and version=?
> This update of version field is performed because collection of quantities is marked as dirty, but Article entity is not relation owner so nothing change in database after this clear. Should it works like this? It looks like a bug because database remain unchanged so version changing is unnecessary in my opinion.
> ******************************************
> session.clear();
> 	
> **** SECOND PROBLEM ***	
> Now I generate true copy of persisted objects.
> Notice that I use HashSet instead of PersistSet which was set during persist operation. This operation is similar to merging objects prepared by SOAP, during communication with remote client for example.
> ***********************
> 		
> Article a1 = new Article();
> a1.setId( a.getId() );
> a1.setName( a.getName() );
> a1.setVersion( a.getVersion() );
> 		
> Quantity q1 = new Quantity();
> q1.setArticle( a1 );
> q1.setName( q.getName() );
> q1.setVersion( q.getVersion() );
> q1.setId( q.getId() );
> 		
> a1.getQuantities().add( q1 );
> 		
> a1 = (Article)session.merge( a1 );
> 	
> session.flush();
> ***** This operation generates following SQLs *****
> Hibernate: select article0_.id as id0_1_, article0_.name as name0_1_, article0_.version as version0_1_, quantities1_.article_id as article4_3_, quantities1_.id as id3_, quantities1_.id as id1_0_, quantities1_.article_id as article4_1_0_, quantities1_.name as name1_0_, quantities1_.version as version1_0_ from Article article0_ left outer join Quantity quantities1_ on article0_.id=quantities1_.article_id where article0_.id=?	
> Hibernate: update Article set name=?, version=? where id=? and version=?
> It looks like problem is located in replaceElements() method of CollectgionType class (or somewhere near it). Maybe I'm wrong but this collection was checked for changes during merge operation (See this select above.) so why it remains  dirty if it contains the same data as database?. I checked this issue on other JPA implementations (OpenJPA for example) and version is not incremented after similar merge operation.
> *****************************************************	
> transaction.rollback();

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

       



More information about the hibernate-issues mailing list