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

Thanks,

I have a similar question that may help to clear things. What happens when i invoke merge() on a new entity with relationships (not marked with any cascading) to detached entities. Specification says:

 If X is an entity merged to X', with a reference to another entity Y, where cascade=MERGE
or cascade=ALL is not specified, then navigation of the same association from X' yields a
reference to a managed object Y' with the same persistent identity as Y.

But when i apply it to an example, Group --- m-1 --- User

User user = new User();
user.setId(1);
Group g = new Group();
g.setName("name")

Group mg = em.merge(g);

When i execute above code 'mg' contains reference to a User entity 1- whose state (eager fields) is not fully loaded, 2- and when i access any lazy this managed User entity no data is fetch. Should not it behave like normal managed entities.





 






Regards,
Jehanzeb Qayyum




On Tue, Mar 23, 2010 at 8:06 PM, James Sutherland <jamesssss@xxxxxxxxx> wrote:

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.

_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users


Back to the top