Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » cascade delete not working when cache is active
cascade delete not working when cache is active [message #527823] Fri, 16 April 2010 14:57 Go to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
We have a simple many to many setup done as two one-to-many: user - user2group - group with cascade delete. If we try to invoke the cascade delete in a simple unittest, then we get an exception.
The unit test only runs correctly when all caching is disabled (when the lines marked with --> below are enabled).
Why does the cache cause problems here?

[EL Warning]: 2010-04-16 16:42:03.734--UnitOfWork(849296)--Thread(Thread[main,5,main] )--Local Exception Stack:
Exception [EclipseLink-7251] (Eclipse Persistence Services - 1.2.0.v20091016-r5565): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [id] of class [nl.knowledgeplaza.profiler.engine.model.User2Group] is mapped to a primary key column in the database. Updates are not allowed.
at org.eclipse.persistence.exceptions.ValidationException.prima ryKeyUpdateDisallowed(ValidationException.java:2372)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMa pping.writeFromObjectIntoRowWithChangeRecord(AbstractDirectM apping.java:1228)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildRowForUpdateWithChangeSet(ObjectBuilder.java:1070)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechan ism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism .java:1104)
at org.eclipse.persistence.queries.UpdateObjectQuery.executeCom mitWithChangeSet(UpdateObjectQuery.java:84)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechan ism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:28 6)
at org.eclipse.persistence.queries.WriteObjectQuery.executeData baseQuery(WriteObjectQuery.java:58)
at org.eclipse.persistence.queries.DatabaseQuery.execute(Databa seQuery.java:670)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitO fWork(DatabaseQuery.java:589)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.execu teInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery. java:109)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.execu teInUnitOfWork(ObjectLevelModifyQuery.java:86)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.int ernalExecuteQuery(UnitOfWorkImpl.java:2858)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1225)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1207)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1167)
at org.eclipse.persistence.internal.sessions.CommitManager.comm itChangedObjectsForClassWithChangeSet(CommitManager.java:233 )
at org.eclipse.persistence.internal.sessions.CommitManager.comm itAllObjectsForClassWithChangeSet(CommitManager.java:163)
at org.eclipse.persistence.internal.sessions.CommitManager.comm itAllObjectsWithChangeSet(CommitManager.java:116)
at org.eclipse.persistence.internal.sessions.AbstractSession.wr iteAllObjectsWithChangeSet(AbstractSession.java:3260)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.com mitToDatabase(UnitOfWorkImpl.java:1400)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUni tOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:521)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.com mitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1505)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUni tOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java: 200)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.com mitAndResume(UnitOfWorkImpl.java:1126)
at org.eclipse.persistence.internal.jpa.transaction.EntityTrans actionImpl.commitInternal(EntityTransactionImpl.java:84)
at org.eclipse.persistence.internal.jpa.transaction.EntityTrans actionImpl.commit(EntityTransactionImpl.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at nl.knowledgeplaza.util.jpa.EntityTransactionExtender.invoke( EntityTransactionExtender.java:86)
at $Proxy10.commit(Unknown Source)
at nl.knowledgeplaza.profiler.engine.unittest.Unittest.testCrea teAndCascadeDelete(Unittest.java:178)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall( FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(Refl ectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(Fr ameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate( InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(Ru nBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(Run Afters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit 4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit 4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java :180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java: 41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java: 173)
at org.junit.internal.runners.statements.RunBefores.evaluate(Ru nBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(Run Afters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.r un(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(Test Execution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe sts(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe sts(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(R emoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main( RemoteTestRunner.java:197)

User:
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, targetEntity = nl.knowledgeplaza.profiler.engine.model.User2Group.class, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE} )
volatile protected java.util.List<nl.knowledgeplaza.profiler.engine.model.User2Group > user2GroupsWhereIAmUser = new java.util.ArrayList<nl.knowledgeplaza.profiler.engine.model.User2Group >();
Group:
@OneToMany(mappedBy = "group", fetch = FetchType.LAZY, targetEntity = nl.knowledgeplaza.profiler.engine.model.User2Group.class, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE} )
volatile protected java.util.List<nl.knowledgeplaza.profiler.engine.model.User2Group > user2GroupsWhereIAmGroup = new java.util.ArrayList<nl.knowledgeplaza.profiler.engine.model.User2Group >();
User2Group:
@ManyToOne(fetch = FetchType.LAZY, targetEntity = nl.knowledgeplaza.profiler.engine.model.User.class, cascade = {CascadeType.REFRESH} ) @JoinColumn(name="user_id")
volatile protected nl.knowledgeplaza.profiler.engine.model.User user;

The unittest does this:

@org.junit.Test
public void testCreateAndCascadeDelete()
{
// get the EM
EntityManager lEntityManager = EclipselinkSetup.createEntityManager(cEntityManagerFactory);
try
{
// create entity
lEntityManager.getTransaction().begin();
// user
User lUser = new User().withUsername("testCreateAndDelete");
lEntityManager.persist(lUser);
// group
Group lGroup = new Group("testCreateAndDelete", "testCreateAndDelete");
lEntityManager.persist(lGroup);
// user2group
User2Group lUser2Group = new User2Group(lUser, lGroup);
lEntityManager.persist(lUser2Group);
// commit
lEntityManager.getTransaction().commit();
--> //lEntityManager.clear();

// cascade delete
lEntityManager.getTransaction().begin();
lEntityManager.remove(lEntityManager.merge(lGroup));
lEntityManager.getTransaction().commit();

// user2group should be gone as well
lUser2Group = User2Group.findByPK(lUser2Group.getId());
org.junit.Assert.assertNull(lUser2Group);
// but user not
lUser = User.findByPK(lUser.getId());
org.junit.Assert.assertNotNull(lUser);
}
finally
{
}
}

To be complete, here is the creation of the EMF and EM:

static public EntityManagerFactory createEntityManagerFactory(Class databasePlatform, Class jdbcDriver, String jdbcUrl, String jdbcUsr, String jdbcPwd, Map<String, Object> options)
{
if (log4j.isInfoEnabled()) log4j.info("Creating an EntityManagerFactory to " + jdbcUsr + " @ " + nl.knowledgeplaza.util.jdbc.Driver.PREFIX + jdbcDriver.getName() + "#" + jdbcUrl);
// setup the factory
Map<String, Object> lOptions = new HashMap<String, Object>();
// always use KPUTIL JDBC Driver so it will automatically log SQL to log4j
lOptions.put(PersistenceUnitProperties.JDBC_DRIVER, nl.knowledgeplaza.util.jdbc.Driver.class.getName());
lOptions.put(PersistenceUnitProperties.JDBC_URL, nl.knowledgeplaza.util.jdbc.Driver.PREFIX + jdbcDriver.getName() + "#" + jdbcUrl);
lOptions.put(PersistenceUnitProperties.JDBC_USER, jdbcUsr);
lOptions.put(PersistenceUnitProperties.JDBC_PASSWORD, jdbcPwd);
lOptions.put(PersistenceUnitProperties.TARGET_DATABASE, (databasePlatform == null? null : databasePlatform.getName()));
lOptions.put(PersistenceUnitProperties.TARGET_SERVER, TargetServer.None);
--> //lOptions.put(PersistenceUnitProperties.CACHE_SHARED_DEFAUL T, "false");
lOptions.put(PersistenceUnitProperties.LOGGING_LEVEL, "fine");
lOptions.put(PersistenceUnitProperties.LOGGING_EXCEPTIONS, "true");
lOptions.put(PersistenceUnitProperties.JDBC_SEQUENCE_CONNECT ION_POOL, "true"); // force sequences to use a separate pool
if (options != null) lOptions.putAll(options);

// setup the factory
EntityManagerFactory lEntityManagerFactory = Persistence.createEntityManagerFactory("kpprofiler", lOptions);

// done
return lEntityManagerFactory;
}

/**
*
*/
static public EntityManager createEntityManager(EntityManagerFactory entityManagerFactory)
{
Map<String, String> lOptions = new HashMap<String, String>();
EntityManager lEntityManager = EntityManagerExtender.wrap( entityManagerFactory.createEntityManager(lOptions) );

// make sure all entitymanagers have flushmode commit
lEntityManager.setFlushMode(FlushModeType.COMMIT);

// done
return lEntityManager;
}
Re: cascade delete not working when cache is active [message #528127 is a reply to message #527823] Mon, 19 April 2010 12:58 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1039
Registered: July 2009
Senior Member
Hello,

What is missing is the User2Group mappings to Id that are involved in the exception. Since you only show the User<->User2Group relations, could the User2Group->Group be using its ID field? Please show the User2Group and verify that when you pass in User and Group in its constructor you are setting both sides of the bi directional relationships.

Best Regards,
Chris
Re: cascade delete not working when cache is active [message #528221 is a reply to message #528127] Mon, 19 April 2010 17:31 Go to previous message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> What is missing is the User2Group mappings to Id that are involved in
> the exception. Since you only show the User<->User2Group relations,
> could the User2Group->Group be using its ID field? Please show the
> User2Group and verify that when you pass in User and Group in its
> constructor you are setting both sides of the bi directional relationships.


I'm setting both sides (its a reversed engineered fully connected BM). Otherwise with cache disabled it shouldn't work either. But I'll get the full definitions.
Previous Topic:cascade insert not working on Eclipselink event
Next Topic:How to approach data tracking?
Goto Forum:
  


Current Time: Wed Nov 26 02:10:53 GMT 2014

Powered by FUDForum. Page generated in 0.01773 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software