Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Entity update and create - optimization

One way to optimize this is to enable the shared cache (which is enabled by
default).  If you then assume the object being merged was first read by this
server at some point, it is likely still in the cache, and the database
access is avoided.

One of the reasons the merge() reads the object from the database, is that
it needs to know what (if anything) changed.  This is very important for
relationships, as if your object has a 1-m and you want to update it without
knowing what changed, you basically need to delete everything, then insert
everything back.  So using merge() is normally the best way to go.

Otherwise, there is an API on EntityManager getReference() which does allow
you to get a handle on an existing object that can be used as a reference to
update or insert a new object.

For your test you seem to be create a new User that matches and existing
user, then a new Group with a reference to this existing user.  To be
correct, the existing User should be read from the EntityManager using
find() or getReference().  Depending on your configuration I think you
should be also able to get just create a new user to work, but I would guess
EclipseLink would try to insert the User by default, so I'm not sure how you
have configured things?

The does exist check and exception to appear odd, you may wish to log a bug
for this, or try it in the latest main build, as I remember something may
have been fixed related to this recently.


jzqa wrote:
> 
> Hi all,
> 
> I am trying to optimize entity update and create operations.
> 
> Question 1:
> 
> In my application i am following detached entity model. To update a
> detached
> entity i have to merge() and then persist. Working as defined in JPA
> specs,
> merge() brings an entity and all its relationships to
> managed state (indpendent of cascade type). So to update X,  entity itself
> and all its relationships are read from database and then X is updated. My
> question is what should i do to optimize it?
> 
> It seems atleast X has to be read so as to determine whether to insert or
> update since same persist() operation is used in both cases, but only its
> PK
> instead of whole state should be read. Is there any
> way to avoid reading relationships.
> 
> Question 2:
> 
> Group (m-1) User (no cascade)
> 
>  //Part-1
> 
> User user = new User();
>  user.setId(3);
>  group = new Group();
>  group.setUser(user);
>  group.setName("test31");
>  //start transaction (RESOURCE LOCAL)
>  em.persist(group);
>  //commit
> 
> //Part-2
>  group = new Group();
>  group.setUser(user);
>  group.setName("test31");
>  //start transaction (RESOURCE LOCAL)
>  em.persist(group);
>  //commit
> 
> 
> If I execute Part-1 only everything works fine. But when Part-2 is
> executed
> with Part-1 i get below error.
> 
> [EL Finest]: 2010-03-16
> 08:48:24.906--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--PERSIST operation called on:
> com.warid.campaign.model.Group@32e28d.
> [EL Finest]: 2010-03-16
> 08:48:24.938--ClientSession(3357006)--Thread(Thread[Main
> Thread,5,main])--Execute query ValueReadQuery(sql="SELECT
> SEQ_CAMPAIGN_GROUP_ID.NEXTVAL FROM DUAL")
> [EL Fine]: 2010-03-16
> 08:48:24.953--ServerSession(1976361)--Connection(3209626)--Thread(Thread[Main
> Thread,5,main])--SELECT SEQ_CAMPAIGN_GROUP_ID.NEXTVAL FROM DUAL
> [EL Finest]: 2010-03-16
> 08:48:25.391--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--assign sequence to the object (31 ->
> com.warid.campaign.model.Group@32e28d)
> [EL Finer]: 2010-03-16
> 08:48:25.406--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--begin unit of work commit
> [EL Finest]: 2010-03-16
> 08:48:25.422--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--Execute query DoesExistQuery(referenceClass=User )
> [EL Fine]: 2010-03-16
> 08:48:25.5--ServerSession(1976361)--Connection(3209626)--Thread(Thread[Main
> Thread,5,main])--SELECT ID FROM TBL_CAMPAIGN_USER WHERE (ID = ?)
>  bind => [3]
> [EL Finer]: 2010-03-16
> 08:48:25.547--ClientSession(3357006)--Connection(3209626)--Thread(Thread[Main
> Thread,5,main])--begin transaction
> [EL Finest]: 2010-03-16
> 08:48:25.547--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--Execute query
> InsertObjectQuery(com.warid.campaign.model.Group@32e28d)
> [EL Fine]: 2010-03-16
> 08:48:25.562--ClientSession(3357006)--Connection(3209626)--Thread(Thread[Main
> Thread,5,main])--INSERT INTO TBL_CAMPAIGN_GROUP (ID, CREATION_DATE, NAME,
> USER_ID) VALUES (?, ?, ?, ?)
>  bind => [31, null, test31, 3]
> [EL Finer]: 2010-03-16
> 08:48:25.594--ClientSession(3357006)--Connection(3209626)--Thread(Thread[Main
> Thread,5,main])--commit transaction
> [EL Finer]: 2010-03-16
> 08:48:25.625--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--end unit of work commit
> [EL Finer]: 2010-03-16
> 08:48:25.625--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--resume unit of work
> [EL Finest]: 2010-03-16
> 08:48:25.625--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--PERSIST operation called on:
> com.warid.campaign.model.Group@39aed6.
> [EL Finest]: 2010-03-16
> 08:48:25.625--ClientSession(3357006)--Thread(Thread[Main
> Thread,5,main])--Execute query ValueReadQuery(sql="SELECT
> SEQ_CAMPAIGN_GROUP_ID.NEXTVAL FROM DUAL")
> [EL Fine]: 2010-03-16
> 08:48:25.625--ServerSession(1976361)--Connection(3209626)--Thread(Thread[Main
> Thread,5,main])--SELECT SEQ_CAMPAIGN_GROUP_ID.NEXTVAL FROM DUAL
> [EL Finest]: 2010-03-16
> 08:48:25.625--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--assign sequence to the object (32 ->
> com.warid.campaign.model.Group@39aed6)
> [EL Finer]: 2010-03-16
> 08:48:25.625--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--begin unit of work commit
> [EL Finer]: 2010-03-16
> 08:48:25.625--ClientSession(3357006)--Connection(3209626)--Thread(Thread[Main
> Thread,5,main])--begin transaction
> [EL Finest]: 2010-03-16
> 08:48:25.625--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--Execute query
> UpdateObjectQuery(com.warid.campaign.model.User@32e28a)
> [EL Warning]: 2010-03-16
> 08:48:25.703--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--Local
> Exception Stack:
> Exception [EclipseLink-7251] (Eclipse Persistence Services -
> 2.0.1.v20100213-r6600):
> org.eclipse.persistence.exceptions.ValidationException
> Exception Description: The attribute [id] of class
> [com.warid.campaign.model.User] is mapped to a primary key column in the
> database. Updates are not allowed.
>  at
> org.eclipse.persistence.exceptions.ValidationException.primaryKeyUpdateDisallowed(ValidationException.java:2400)
>  at
> org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.writeFromObjectIntoRowWithChangeRecord(AbstractDirectMapping.java:1286)
>  at
> org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildRowForUpdateWithChangeSet(ObjectBuilder.java:1072)
>  at
> org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:1107)
>  at
> org.eclipse.persistence.queries.UpdateObjectQuery.executeCommitWithChangeSet(UpdateObjectQuery.java:84)
>  at
> org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:286)
>  at
> org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
>  at
> org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:675)
>  at
> org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:589)
>  at
> org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:109)
>  at
> org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:86)
>  at
> org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2857)
>  at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1225)
>  at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1207)
>  at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1167)
>  at
> org.eclipse.persistence.internal.sessions.CommitManager.commitChangedObjectsForClassWithChangeSet(CommitManager.java:233)
>  at
> org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsForClassWithChangeSet(CommitManager.java:163)
>  at
> org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:116)
>  at
> org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3260)
>  at
> org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1403)
>  at
> org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:547)
>  at
> org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1508)
>  at
> org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:200)
>  at
> org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1129)
>  at
> org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
>  at
> org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
>  at com.warid.campaign.model.dao.DAOLocalImpl.create(DAOLocalImpl.java:24)
>  at com.warid.campaign.model.dao.DAOLocalImpl.main(DAOLocalImpl.java:53)
> 
> [EL Finer]: 2010-03-16
> 08:48:25.719--ClientSession(3357006)--Connection(3209626)--Thread(Thread[Main
> Thread,5,main])--rollback transaction
> [EL Finer]: 2010-03-16
> 08:48:25.734--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--release unit of work
> [EL Finer]: 2010-03-16
> 08:48:25.734--ClientSession(3357006)--Thread(Thread[Main
> Thread,5,main])--client released
> Exception in thread "Main Thread" javax.persistence.RollbackException:
> Exception [EclipseLink-7251] (Eclipse Persistence Services -
> 2.0.1.v20100213-r6600):
> org.eclipse.persistence.exceptions.ValidationException
> Exception Description: The attribute [id] of class
> [com.warid.campaign.model.User] is mapped to a primary key column in the
> database. Updates are not allowed.
>  at
> org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
>  at
> org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
>  at com.warid.campaign.model.dao.DAOLocalImpl.create(DAOLocalImpl.java:24)
>  at com.warid.campaign.model.dao.DAOLocalImpl.main(DAOLocalImpl.java:53)
> Caused by: Exception [EclipseLink-7251] (Eclipse Persistence Services -
> 2.0.1.v20100213-r6600):
> org.eclipse.persistence.exceptions.ValidationException
> Exception Description: The attribute [id] of class
> [com.warid.campaign.model.User] is mapped to a primary key column in the
> database. Updates are not allowed.
>  at
> org.eclipse.persistence.exceptions.ValidationException.primaryKeyUpdateDisallowed(ValidationException.java:2400)
>  at
> org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.writeFromObjectIntoRowWithChangeRecord(AbstractDirectMapping.java:1286)
>  at
> org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildRowForUpdateWithChangeSet(ObjectBuilder.java:1072)
>  at
> org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:1107)
>  at
> org.eclipse.persistence.queries.UpdateObjectQuery.executeCommitWithChangeSet(UpdateObjectQuery.java:84)
>  at
> org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:286)
>  at
> org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
>  at
> org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:675)
>  at
> org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:589)
>  at
> org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:109)
>  at
> org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:86)
>  at
> org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2857)
>  at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1225)
>  at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1207)
>  at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1167)
>  at
> org.eclipse.persistence.internal.sessions.CommitManager.commitChangedObjectsForClassWithChangeSet(CommitManager.java:233)
>  at
> org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsForClassWithChangeSet(CommitManager.java:163)
>  at
> org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:116)
>  at
> org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3260)
>  at
> org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1403)
>  at
> org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:547)
>  at
> org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1508)
>  at
> org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:200)
>  at
> org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1129)
>  at
> org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
>  ... 3 more
> 
> 
> Question 3:
> 
> Why following validation is absolutely necessary (as depicted in above
> excerpt)
> 
> [EL Finest]: 2010-03-16
> 08:48:25.422--UnitOfWork(3354677)--Thread(Thread[Main
> Thread,5,main])--Execute query DoesExistQuery(referenceClass=User )
> [EL Fine]: 2010-03-16
> 08:48:25.5--ServerSession(1976361)--Connection(3209626)--Thread(Thread[Main
> Thread,5,main])--SELECT ID FROM TBL_CAMPAIGN_USER WHERE (ID =
> 
> 
> Thanks
> 
> Regards,
> Jehanzeb Qayyum
> 
> 
> 


-----
http://wiki.eclipse.org/User:James.sutherland.oracle.com James Sutherland 
http://www.eclipse.org/eclipselink/
 EclipseLink ,  http://www.oracle.com/technology/products/ias/toplink/
TopLink 
Wiki:  http://wiki.eclipse.org/EclipseLink EclipseLink , 
http://wiki.oracle.com/page/TopLink TopLink 
Forums:  http://forums.oracle.com/forums/forum.jspa?forumID=48 TopLink , 
http://www.nabble.com/EclipseLink-f26430.html EclipseLink 
Book:  http://en.wikibooks.org/wiki/Java_Persistence Java Persistence 
-- 
View this message in context: http://old.nabble.com/Entity-update-and-create---optimization-tp27919157p28002272.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.



Back to the top