openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sławomir Wojtasiak (JIRA) <j...@apache.org>
Subject [jira] Created: (OPENJPA-444) Unnecessary updates during flush operation.
Date Sun, 18 Nov 2007 09:28:43 GMT
Unnecessary updates during flush operation.
-------------------------------------------

                 Key: OPENJPA-444
                 URL: https://issues.apache.org/jira/browse/OPENJPA-444
             Project: OpenJPA
          Issue Type: Bug
          Components: kernel
    Affects Versions: 1.0.1
         Environment: OpenJPA without field tracking. (JDK 5.0 )
            Reporter: Sławomir Wojtasiak


OpenJPA performs unnecessary updates during flush operation. For example:

When we are trying to persist versioned entity with collection of other entities:

|Article|1-------------*|Quantity|    ( Relation owner. )


************ CODE *************

EntityManagerFactory factory = Persistence.createEntityManagerFactory( "testjpa", System.getProperties()
);
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();

Article a = new Article();
a.setName( "atricle" );
		
Quantity q = new Quantity();
q.setName( "quantity" );
q.setArticle( a );
		
a.getQuantities().add( q );
		
em.persist( a );

em.flush();
em.flush();

************* END OF CODE ************

Following queries are generated after first flush operation:

SELECT SEQUENCE_VALUE FROM OPENJPA_SEQUENCE_TABLE WHERE ID = ? FOR UPDATE [params=(int) 0]
UPDATE OPENJPA_SEQUENCE_TABLE SET SEQUENCE_VALUE = ? WHERE ID = ? AND SEQUENCE_VALUE = ? [params=(long)
2651, (int) 0, (long) 2601]
SELECT SEQUENCE_VALUE FROM OPENJPA_SEQUENCE_TABLE WHERE ID = ? FOR UPDATE [params=(int) 0]
UPDATE OPENJPA_SEQUENCE_TABLE SET SEQUENCE_VALUE = ? WHERE ID = ? AND SEQUENCE_VALUE = ? [params=(long)
2701, (int) 0, (long) 2651]
INSERT INTO Article (id, name, version) VALUES (?, ?, ?) [params=(long) 2601, (String) atricle,
(int) 1]
INSERT INTO Quantity (id, name, version, article_id) VALUES (?, ?, ?, ?) [params=(long) 2651,
(String) quantity, (int) 1, (long) 2601]

Everything looks ok but after next flush we will get version update:

UPDATE Article SET version = ? WHERE id = ? AND version = ? [params=(int) 2, (long) 2601,
(int) 1]

I am not completely sure that this analysis is correct, but I hope it helps anyway:

During persist operation SaveFieldManager sets collection of quantities as unloaded and unsaved
field (Because this field is mutable). During next flush, StateManager checks which fields
are dirty by comparing its values to those stored by SaveFieldManager. Method dirtyCheck()
of the StateManager is responsible for that. (It's necessary taking into consideration fact
that I do not use OpenJPA enhancer with JDK 5.0).  SaveFieldManager always returns false from
its isFieldEqual() method because this collection (Collection of quantities) is treated as
unsaved ( Comment from OpenJPA code:  if the field is not available, assume that it has changed)
so StateManager sets it as dirty and clears its flush bit. Then AbstractUpdateManager try
to add UPDATE_ACTION for this dirty collection, but with no effect because this field is not
set as updatable and insertable ( I think so. ). In next step AbstractUpdateManager adds UPDATE_ACTION
for version field because StateManager is marked as dirty. It causes unnecessary update of
entity version field because nothing changed in the database. 

I didn't check how it works with field tracking.




-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message