persistence@glassfish.java.net

Re: PreRemove ConcurrentModificationException

From: Greg Ederer <greg_at_ergonosis.com>
Date: Thu, 14 Jun 2007 16:01:29 -0700

Hi Markus,

When I remove the @PreRemove from both Article and ArticlePlacement, and
em.remove(articlePlacement), I get the following stack trace:

Removing class com.acadept.model.article.ArticlePlacement with id 1
Local Exception Stack:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0 (Build b50a-beta3 (06/13/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: update or delete on table "article_placement" violates foreign key constraint "fk_article_group_article_placement_articleplacements_id" on table "article_group_article_placement"
  Detail: Key (id)=(1) is still referenced from table "article_group_article_placement".
Error Code: 0
Call: DELETE FROM article_placement WHERE (ID = ?)
        bind => [1]
Query: DeleteObjectQuery(com.acadept.model.ArticlePlacement[id=1])
        at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:311)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:654)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:703)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:492)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:452)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeCall(AbstractSession.java:690)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:214)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.deleteObject(DatasourceCallQueryMechanism.java:205)
        at oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.deleteObject(StatementQueryMechanism.java:130)
        at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.deleteObjectForWrite(DatabaseQueryMechanism.java:258)
        at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeCommit(DeleteObjectQuery.java:98)
        at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.executeWrite(DatabaseQueryMechanism.java:335)
        at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:111)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:628)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:555)
        at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:138)
        at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:125)
        at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:110)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2233)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:952)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
        at oracle.toplink.essentials.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:338)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1047)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:403)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1126)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:2443)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:202)
        at oracle.toplink.essentials.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:131)
        at oracle.toplink.essentials.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:91)
        at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:419)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:371)
        at com.sun.enterprise.distributedtx.UserTransactionImpl.commit(UserTransactionImpl.java:197)
        at com.acadept.web.controller.JSONFormController.handleRequestInternal(JSONFormController.java:129)
        at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:839)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:774)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:460)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:425)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:317)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:110)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:135)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:229)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:286)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
        at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:288)
        at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:268)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:631)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:562)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:803)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:339)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:261)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:212)
        at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
        at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "article_placement" violates foreign key constraint "fk_article_group_article_placement_articleplacements_id" on table "article_group_article_placement"
  Detail: Key (id)=(1) is still referenced from table "article_group_article_placement".
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:351)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:305)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:647)
        ... 93 more
Local Exception Stack:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0 (Build b50a-beta3 (06/13/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: update or delete on table "article_placement" violates foreign key constraint "fk_article_group_article_placement_articleplacements_id" on table "article_group_article_placement"
  Detail: Key (id)=(1) is still referenced from table "article_group_article_placement".
Error Code: 0
Call: DELETE FROM article_placement WHERE (ID = ?)
        bind => [1]
Query: DeleteObjectQuery(com.acadept.model.ArticlePlacement[id=1])
        at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:311)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:654)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:703)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:492)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:452)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeCall(AbstractSession.java:690)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:214)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.deleteObject(DatasourceCallQueryMechanism.java:205)
        at oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.deleteObject(StatementQueryMechanism.java:130)
        at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.deleteObjectForWrite(DatabaseQueryMechanism.java:258)
        at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeCommit(DeleteObjectQuery.java:98)
        at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.executeWrite(DatabaseQueryMechanism.java:335)
        at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:111)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:628)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:555)
        at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:138)
        at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:125)
        at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:110)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2233)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:952)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
        at oracle.toplink.essentials.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:338)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1047)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:403)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1126)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:2443)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:202)
        at oracle.toplink.essentials.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:131)
        at oracle.toplink.essentials.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:91)
        at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:419)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:371)
        at com.sun.enterprise.distributedtx.UserTransactionImpl.commit(UserTransactionImpl.java:197)
        at com.acadept.web.controller.JSONFormController.handleRequestInternal(JSONFormController.java:129)
        at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:839)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:774)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:460)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:425)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:317)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:110)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:135)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:229)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:286)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
        at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:288)
        at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:268)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:631)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:562)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:803)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:339)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:261)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:212)
        at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
        at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "article_placement" violates foreign key constraint "fk_article_group_article_placement_articleplacements_id" on table "article_group_article_placement"
  Detail: Key (id)=(1) is still referenced from table "article_group_article_placement".
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:351)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:305)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:647)
        ... 93 more
StandardWrapperValve[acadept]: PWC1406: Servlet.service() for servlet acadept threw exception
javax.transaction.RollbackException: Transaction marked for rollback.
        at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:440)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:371)
        at com.sun.enterprise.distributedtx.UserTransactionImpl.commit(UserTransactionImpl.java:197)
        at com.acadept.web.controller.JSONFormController.handleRequestInternal(JSONFormController.java:129)
        at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:839)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:774)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:460)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:425)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:317)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:110)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:135)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:229)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:286)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
        at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:288)
        at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:268)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:631)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:562)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:803)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:339)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:261)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:212)
        at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
        at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)

When I em.remove(article) without @PreRemoves, I get:

Removing class com.acadept.model.article.Article with id 3
Local Exception Stack:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0 (Build b50a-beta3 (06/13/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: update or delete on table "article_placement" violates foreign key constraint "fk_article_group_article_placement_articleplacements_id" on table "article_group_article_placement"
  Detail: Key (id)=(1) is still referenced from table "article_group_article_placement".
Error Code: 0
Call: DELETE FROM article_placement WHERE (ID = ?)
        bind => [1]
Query: DeleteObjectQuery(com.acadept.model.ArticlePlacement[id=1])
        at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:311)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:654)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:703)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:492)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:452)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeCall(AbstractSession.java:690)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:214)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.deleteObject(DatasourceCallQueryMechanism.java:205)
        at oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.deleteObject(StatementQueryMechanism.java:130)
        at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.deleteObjectForWrite(DatabaseQueryMechanism.java:258)
        at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeCommit(DeleteObjectQuery.java:98)
        at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.executeWrite(DatabaseQueryMechanism.java:335)
        at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:111)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:628)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:555)
        at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:138)
        at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:125)
        at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:110)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2233)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:952)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
        at oracle.toplink.essentials.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:338)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1047)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:403)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1126)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:2443)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:202)
        at oracle.toplink.essentials.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:131)
        at oracle.toplink.essentials.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:91)
        at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:419)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:371)
        at com.sun.enterprise.distributedtx.UserTransactionImpl.commit(UserTransactionImpl.java:197)
        at com.acadept.web.controller.JSONFormController.handleRequestInternal(JSONFormController.java:129)
        at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:839)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:774)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:460)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:425)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:317)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:110)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:135)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:229)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:286)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
        at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:288)
        at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:268)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:631)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:562)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:803)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:339)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:261)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:212)
        at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
        at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "article_placement" violates foreign key constraint "fk_article_group_article_placement_articleplacements_id" on table "article_group_article_placement"
  Detail: Key (id)=(1) is still referenced from table "article_group_article_placement".
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:351)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:305)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:647)
        ... 93 more
Local Exception Stack:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0 (Build b50a-beta3 (06/13/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: update or delete on table "article_placement" violates foreign key constraint "fk_article_group_article_placement_articleplacements_id" on table "article_group_article_placement"
  Detail: Key (id)=(1) is still referenced from table "article_group_article_placement".
Error Code: 0
Call: DELETE FROM article_placement WHERE (ID = ?)
        bind => [1]
Query: DeleteObjectQuery(com.acadept.model.ArticlePlacement[id=1])
        at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:311)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:654)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:703)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:492)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:452)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeCall(AbstractSession.java:690)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:214)
        at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.deleteObject(DatasourceCallQueryMechanism.java:205)
        at oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.deleteObject(StatementQueryMechanism.java:130)
        at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.deleteObjectForWrite(DatabaseQueryMechanism.java:258)
        at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeCommit(DeleteObjectQuery.java:98)
        at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.executeWrite(DatabaseQueryMechanism.java:335)
        at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:111)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:628)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:555)
        at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:138)
        at oracle.toplink.essentials.queryframework.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:125)
        at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:110)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2233)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:952)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
        at oracle.toplink.essentials.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:338)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1047)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:403)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1126)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:2443)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:202)
        at oracle.toplink.essentials.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:131)
        at oracle.toplink.essentials.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:91)
        at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:419)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:371)
        at com.sun.enterprise.distributedtx.UserTransactionImpl.commit(UserTransactionImpl.java:197)
        at com.acadept.web.controller.JSONFormController.handleRequestInternal(JSONFormController.java:129)
        at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:839)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:774)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:460)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:425)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:317)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:110)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:135)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:229)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:286)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
        at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:288)
        at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:268)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:631)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:562)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:803)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:339)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:261)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:212)
        at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
        at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "article_placement" violates foreign key constraint "fk_article_group_article_placement_articleplacements_id" on table "article_group_article_placement"
  Detail: Key (id)=(1) is still referenced from table "article_group_article_placement".
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:351)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:305)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:647)
        ... 93 more
StandardWrapperValve[acadept]: PWC1406: Servlet.service() for servlet acadept threw exception
javax.transaction.RollbackException: Transaction marked for rollback.
        at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:440)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:371)
        at com.sun.enterprise.distributedtx.UserTransactionImpl.commit(UserTransactionImpl.java:197)
        at com.acadept.web.controller.JSONFormController.handleRequestInternal(JSONFormController.java:129)
        at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:839)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:774)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:460)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:425)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
        at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:317)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
        at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:110)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:135)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:229)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:286)
        at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
        at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
        at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:288)
        at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:624)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:268)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:631)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:562)
        at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:803)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:339)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:261)
        at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:212)
        at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
        at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)


Restoring the @PreRemove callbacks to both classes resolves these problems.

Also, I upgraded to v2b50a.

Thanks for the tip on removing the return value from merge!

Cheers,

Greg

Markus Fuchs wrote:
> Hi Greg,
>
> I can't see, why you should get a foreign key violation removing an
> ArticlePlacement, since ArticlePlacement owns the the relationships to
> Article and ArticleGroup. To only other relationship is a
> uni-directional OneToMany between Article and ArticleGroup. But
> neither Articles nor ArticleGroups are removed, correct?
>
> BTW, in
>
>> utx.begin();
>> em.merge(o);
>> em.joinTransaction();
>> em.remove(o);
>> utx.commit();
>>
> you should call the remove operation on the managed copy returned by
> em.merge(o)
>
> Thanks,
>
> -- markus.
>> Where javaType is com.acadept.model.article.ArticlePlacement.
>>
>> Greg Ederer wrote:
>>> Markus Fuchs wrote:
>>>> Hi Greg,
>>>>
>>>> That sounds like a bug to me. Could you send me your pojos and a
>>>> small snipplet of your application code as a test case?
>>>>
>>>> You are talking about em.remove(article) and no @PreRemove in
>>>> ArticlePlacement resulting in a foreign key violation, correct?
>>>>
>>> Actually, I get the fk violation when I em.remove(articlePlacement)
>>> w/o the @PreRemove. Does this still sound like a bug, or is it just
>>> my incorrect way of doing things?
>>>
>>> Code below.
>>>
>>> Cheers,
>>>
>>> Greg
>>>
>>> In my servlet:
>>>
>>> Object o = em.find(javaType, id);
>>> responseMap.put("javaType", javaType);
>>> responseMap.put("id", id);
>>> utx.begin();
>>> em.merge(o);
>>> em.joinTransaction();
>>> em.remove(o);
>>> utx.commit();
>>>
>>>
>>> /*
>>> * Article.java
>>> *
>>> * Created on May 7, 2007, 2:15 PM
>>> *
>>> * To change this template, choose Tools | Template Manager
>>> * and open the template in the editor.
>>> */
>>>
>>> package com.acadept.model.article;
>>>
>>> import com.acadept.model.*;
>>> import java.io.Serializable;
>>> import java.util.ArrayList;
>>> import java.util.Date;
>>> import java.util.List;
>>> import javax.persistence.CascadeType;
>>> import javax.persistence.Column;
>>> import javax.persistence.Entity;
>>> import javax.persistence.GeneratedValue;
>>> import javax.persistence.GenerationType;
>>> import javax.persistence.Id;
>>> import javax.persistence.ManyToOne;
>>> import javax.persistence.OneToMany;
>>> import javax.persistence.OneToOne;
>>> import javax.persistence.PreRemove;
>>> import javax.persistence.SequenceGenerator;
>>> import javax.persistence.Temporal;
>>> import javax.persistence.TemporalType;
>>>
>>> /**
>>> * Entity class Article
>>> * * @author gregederer
>>> */
>>> @Entity
>>> public class Article implements Serializable
>>> {
>>> @Id
>>> @GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
>>> "ARTICLE_SEQ_GENERATOR")
>>> @SequenceGenerator(name = "ARTICLE_SEQ_GENERATOR", sequenceName =
>>> "ARTICLE_ID_SEQ")
>>> private Long id;
>>>
>>> @ManyToOne
>>> private ArticleCategory articleCategory;
>>>
>>> @OneToMany(mappedBy = "article", cascade=CascadeType.ALL)
>>> private List<ArticlePlacement> articlePlacements = new
>>> ArrayList<ArticlePlacement>();
>>>
>>> @Column(name="lead_in_image")
>>> private String leadInImage;
>>>
>>> private String title;
>>>
>>> private String subTitle;
>>>
>>> @Column(name="lead_in", columnDefinition="text")
>>> private String leadIn;
>>>
>>> @Column(columnDefinition="text")
>>> private String body;
>>>
>>> @OneToOne
>>> private AppUser poster;
>>>
>>> @Column(name="publication_date")
>>> @Temporal(TemporalType.DATE)
>>> private Date createdDate;
>>>
>>> /** Creates a new instance of Article */
>>> public Article()
>>> {
>>> }
>>>
>>> /**
>>> * Gets the id of this Article.
>>> * @return the id
>>> */
>>> public Long getId()
>>> {
>>> return this.id;
>>> }
>>>
>>> /**
>>> * Sets the id of this Article to the specified value.
>>> * @param id the new id
>>> */
>>> public void setId(Long id)
>>> {
>>> this.id = id;
>>> }
>>>
>>> /**
>>> * Returns a hash code value for the object. This implementation
>>> computes * a hash code value based on the id fields in this object.
>>> * @return a hash code value for this object.
>>> */
>>> @Override
>>> public int hashCode()
>>> {
>>> int hash = 0;
>>> hash += (this.getId() != null ? this.getId().hashCode() : 0);
>>> return hash;
>>> }
>>>
>>> /**
>>> * Determines whether another object is equal to this Article. The
>>> result is * <code>true</code> if and only if the argument is not
>>> null and is a Article object that * has the same id field values
>>> as this object.
>>> * @param object the reference object with which to compare
>>> * @return <code>true</code> if this object is the same as the
>>> argument;
>>> * <code>false</code> otherwise.
>>> */
>>> @Override
>>> public boolean equals(Object object)
>>> {
>>> // TODO: Warning - this method won't work in the case the id
>>> fields are not set
>>> if (!(object instanceof Article)) {
>>> return false;
>>> }
>>> Article other = (Article)object;
>>> // If both are the same object, return true
>>> if(this == other)
>>> {
>>> return true;
>>> }
>>> // If both objects have ids, compare their ids
>>> if(this.getId() != null && other.getId() != null)
>>> {
>>> // If their ids are equal, return true
>>> if(this.getId().equals(other.getId()))
>>> {
>>> return true;
>>> }
>>> // Otherwise, return false
>>> else
>>> {
>>> return false;
>>> }
>>> }
>>> // If one or both do not have ids, compare their 'natural keys'
>>> if(this.getTitle() != null &&
>>> this.getTitle().equals(other.getTitle())
>>> && this.getCreatedDate() != null &&
>>> this.getCreatedDate().equals(other.getCreatedDate())
>>> && this.getPoster() != null &&
>>> this.getPoster().equals(other.getPoster())
>>> )
>>> {
>>> return true;
>>> }
>>> return false;
>>> }
>>>
>>> /**
>>> * Returns a string representation of the object. This
>>> implementation constructs * that representation based on the id
>>> fields.
>>> * @return a string representation of the object.
>>> */
>>> @Override
>>> public String toString()
>>> {
>>> return "com.acadept.model.Article[id=" + getId() + "]";
>>> }
>>>
>>> public ArticleCategory getArticleCategory()
>>> {
>>> return articleCategory;
>>> }
>>>
>>> public void setArticleCategory(ArticleCategory articleCategory)
>>> {
>>> this.articleCategory = articleCategory;
>>> articleCategory.addArticle(this);
>>> }
>>>
>>> public String getTitle()
>>> {
>>> return title;
>>> }
>>>
>>> public void setTitle(String title)
>>> {
>>> this.title = title;
>>> }
>>>
>>> public String getSubTitle()
>>> {
>>> return subTitle;
>>> }
>>>
>>> public void setSubTitle(String subTitle)
>>> {
>>> this.subTitle = subTitle;
>>> }
>>>
>>> public String getLeadIn()
>>> {
>>> return leadIn;
>>> }
>>>
>>> public void setLeadIn(String leadIn)
>>> {
>>> this.leadIn = leadIn;
>>> }
>>>
>>> public String getBody()
>>> {
>>> return body;
>>> }
>>>
>>> public void setBody(String body)
>>> {
>>> this.body = body;
>>> }
>>>
>>> public AppUser getPoster()
>>> {
>>> return poster;
>>> }
>>>
>>> public void setPoster(AppUser poster)
>>> {
>>> this.poster = poster;
>>> }
>>>
>>> public Date getCreatedDate()
>>> {
>>> return createdDate;
>>> }
>>>
>>> public void setCreatedDate(Date createdDate)
>>> {
>>> this.createdDate = createdDate;
>>> }
>>>
>>> public String getLeadInImage()
>>> {
>>> return leadInImage;
>>> }
>>>
>>> public void setLeadInImage(String leadInImage)
>>> {
>>> this.leadInImage = leadInImage;
>>> }
>>>
>>> public List<ArticlePlacement> getArticlePlacements()
>>> {
>>> return articlePlacements;
>>> }
>>>
>>> public void setArticlePlacements(List<ArticlePlacement>
>>> articlePlacements)
>>> {
>>> this.articlePlacements = articlePlacements;
>>> }
>>>
>>> public void addArticlePlacement(ArticlePlacement articlePlacement)
>>> {
>>> if(this.getArticlePlacements().contains(articlePlacement))
>>> {
>>> return;
>>> }
>>> getArticlePlacements().add(articlePlacement);
>>> articlePlacement.setArticle(this);
>>> }
>>>
>>> public void removeArticlePlacement(ArticlePlacement articlePlacement)
>>> {
>>> getArticlePlacements().remove(articlePlacement);
>>> articlePlacement.setArticle(null);
>>> }
>>>
>>> @PreRemove
>>> public void beforeRemove()
>>> {
>>> List<ArticlePlacement> articlePlacements = getArticlePlacements();
>>> for(ArticlePlacement ap : articlePlacements)
>>> {
>>> ap.setArticle(null);
>>> }
>>> }
>>> }
>>>
>>>
>>> /*
>>> * ArticlePlacement.java
>>> *
>>> * Created on May 7, 2007, 2:32 PM
>>> *
>>> * To change this template, choose Tools | Template Manager
>>> * and open the template in the editor.
>>> */
>>>
>>> package com.acadept.model.article;
>>>
>>> import java.io.Serializable;
>>> import java.util.Date;
>>> import javax.persistence.Column;
>>> import javax.persistence.Entity;
>>> import javax.persistence.GeneratedValue;
>>> import javax.persistence.GenerationType;
>>> import javax.persistence.Id;
>>> import javax.persistence.ManyToOne;
>>> import javax.persistence.PreRemove;
>>> import javax.persistence.SequenceGenerator;
>>> import javax.persistence.Table;
>>> import javax.persistence.Temporal;
>>> import javax.persistence.TemporalType;
>>>
>>> /**
>>> * Entity class ArticlePlacement
>>> *
>>> * @author gregederer
>>> */
>>> @Entity
>>> @Table(name="article_placement")
>>> public class ArticlePlacement implements Serializable
>>> {
>>> @Id
>>> @GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
>>> "ARTICLE_PLACEMENT_SEQ_GENERATOR")
>>> @SequenceGenerator(name = "ARTICLE_PLACEMENT_SEQ_GENERATOR",
>>> sequenceName = "ARTICLE_PLACEMENT_ID_SEQ")
>>> private Long id;
>>>
>>> @ManyToOne
>>> private Article article;
>>>
>>> @ManyToOne
>>> private ArticleGroup articleGroup;
>>>
>>> @Temporal(value = TemporalType.TIMESTAMP)
>>> @Column(name="order_position")
>>> private Date position;
>>>
>>> @Temporal(TemporalType.TIMESTAMP)
>>> private Date startRunDate;
>>>
>>> @Temporal(TemporalType.TIMESTAMP)
>>> private Date endRunDate;
>>>
>>> /** Creates a new instance of ArticlePlacement */
>>> public ArticlePlacement()
>>> {
>>> }
>>>
>>> /**
>>> * Gets the id of this ArticlePlacement.
>>> * @return the id
>>> */
>>> public Long getId()
>>> {
>>> return this.id;
>>> }
>>>
>>> /**
>>> * Sets the id of this ArticlePlacement to the specified value.
>>> * @param id the new id
>>> */
>>> public void setId(Long id)
>>> {
>>> this.id = id;
>>> }
>>>
>>> /**
>>> * Returns a hash code value for the object. This implementation
>>> computes
>>> * a hash code value based on the id fields in this object.
>>> * @return a hash code value for this object.
>>> */
>>> @Override
>>> public int hashCode()
>>> {
>>> int hash = 0;
>>> hash += (this.getId() != null ? this.getId().hashCode() : 0);
>>> return hash;
>>> }
>>>
>>> /**
>>> * Determines whether another object is equal to this
>>> ArticlePlacement. The result is
>>> * <code>true</code> if and only if the argument is not null and is
>>> a ArticlePlacement object that
>>> * has the same id field values as this object.
>>> * @param object the reference object with which to compare
>>> * @return <code>true</code> if this object is the same as the
>>> argument;
>>> * <code>false</code> otherwise.
>>> */
>>> @Override
>>> public boolean equals(Object object)
>>> {
>>> if (!(object instanceof ArticlePlacement))
>>> {
>>> return false;
>>> }
>>> ArticlePlacement other = (ArticlePlacement)object;
>>> // If both are the same object, return true
>>> if(this == other)
>>> {
>>> return true;
>>> }
>>> // If both objects have ids, compare their ids
>>> if(this.getId() != null && other.getId() != null)
>>> {
>>> // If their ids are equal, return true
>>> if(this.getId().equals(other.getId()))
>>> {
>>> return true;
>>> }
>>> // Otherwise, return false
>>> else
>>> {
>>> return false;
>>> }
>>> }
>>> // If one or both do not have ids, compare their 'natural keys'
>>> if(this.getArticle() != null &&
>>> this.getArticle().equals(other.getArticle())
>>> && this.getArticleGroup() != null &&
>>> this.getArticleGroup().equals(other.getArticleGroup())
>>> )
>>> {
>>> return true;
>>> }
>>> return false;
>>> }
>>>
>>> /**
>>> * Returns a string representation of the object. This
>>> implementation constructs
>>> * that representation based on the id fields.
>>> * @return a string representation of the object.
>>> */
>>> @Override
>>> public String toString()
>>> {
>>> return "com.acadept.model.ArticlePlacement[id=" + getId() + "]";
>>> }
>>>
>>> public Article getArticle()
>>> {
>>> return article;
>>> }
>>>
>>> public void setArticle(Article article)
>>> {
>>> this.article = article;
>>> if(article != null)
>>> {
>>> article.addArticlePlacement(this);
>>> }
>>> }
>>>
>>> public ArticleGroup getArticleGroup()
>>> {
>>> return articleGroup;
>>> }
>>>
>>> public void setArticleGroup(ArticleGroup articleGroup)
>>> {
>>> this.articleGroup = articleGroup;
>>> if(articleGroup != null)
>>> {
>>> articleGroup.addArticlePlacement(this);
>>> }
>>> }
>>>
>>> public Date getPosition()
>>> {
>>> return position;
>>> }
>>>
>>> public void setPosition(Date position)
>>> {
>>> this.position = position;
>>> }
>>>
>>> public Date getStartRunDate()
>>> {
>>> return startRunDate;
>>> }
>>>
>>> public void setStartRunDate(Date startRunDate)
>>> {
>>> this.startRunDate = startRunDate;
>>> }
>>>
>>> public Date getEndRunDate()
>>> {
>>> return endRunDate;
>>> }
>>>
>>> public void setEndRunDate(Date endRunDate)
>>> {
>>> this.endRunDate = endRunDate;
>>> }
>>>
>>> @PreRemove
>>> public void beforeRemove()
>>> {
>>> getArticleGroup().removeArticlePlacement(this);
>>> if(getArticle() != null)
>>> {
>>> getArticle().removeArticlePlacement(this);
>>> }
>>> }
>>> }
>>>
>>>
>>> /*
>>> * ArticleGroup.java
>>> *
>>> * Created on May 7, 2007, 2:27 PM
>>> *
>>> * To change this template, choose Tools | Template Manager
>>> * and open the template in the editor.
>>> */
>>>
>>> package com.acadept.model.article;
>>>
>>> import com.acadept.model.*;
>>> import java.io.Serializable;
>>> import java.util.ArrayList;
>>> import java.util.List;
>>> import java.util.logging.Logger;
>>> import javax.persistence.CascadeType;
>>> import javax.persistence.Column;
>>> import javax.persistence.Entity;
>>> import javax.persistence.GeneratedValue;
>>> import javax.persistence.GenerationType;
>>> import javax.persistence.Id;
>>> import javax.persistence.OneToMany;
>>> import javax.persistence.OrderBy;
>>> import javax.persistence.SequenceGenerator;
>>> import javax.persistence.Table;
>>>
>>> /**
>>> * Entity class ArticleGroup
>>> * * @author gregederer
>>> */
>>> @Entity
>>> @Table(name="article_group")
>>> public class ArticleGroup implements Serializable
>>> {
>>> private static Logger logger =
>>> Logger.getLogger(ContentGroup.class.getName());
>>>
>>> @Id
>>> @GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
>>> "ARTICLE_GROUP_SEQ_GENERATOR")
>>> @SequenceGenerator(name = "ARTICLE_GROUP_SEQ_GENERATOR",
>>> sequenceName = "ARTICLE_GROUP_ID_SEQ")
>>> private Long id;
>>>
>>> @Column(name="content_name", unique=true)
>>> private String name;
>>>
>>> @Column(columnDefinition="text")
>>> private String description;
>>>
>>> @OneToMany(cascade=CascadeType.ALL)
>>> @OrderBy("position ASC")
>>> private List<ArticlePlacement> articlePlacements = new
>>> ArrayList<ArticlePlacement>();
>>>
>>> /**
>>> * Gets the id of this ArticleGroup.
>>> * @return the id
>>> */
>>> public Long getId()
>>> {
>>> return this.id;
>>> }
>>>
>>> /**
>>> * Sets the id of this ArticleGroup to the specified value.
>>> * @param id the new id
>>> */
>>> public void setId(Long id)
>>> {
>>> this.id = id;
>>> }
>>>
>>> /**
>>> * Returns a hash code value for the object. This implementation
>>> computes * a hash code value based on the id fields in this object.
>>> * @return a hash code value for this object.
>>> */
>>> @Override
>>> public int hashCode()
>>> {
>>> int hash = 0;
>>> hash += (this.getId() != null ? this.getId().hashCode() : 0);
>>> return hash;
>>> }
>>>
>>> /**
>>> * Determines whether another object is equal to this
>>> ArticleGroup. The result is * <code>true</code> if and only if
>>> the argument is not null and is a ArticleGroup object that * has
>>> the same id field values as this object.
>>> * @param object the reference object with which to compare
>>> * @return <code>true</code> if this object is the same as the
>>> argument;
>>> * <code>false</code> otherwise.
>>> */
>>> @Override
>>> public boolean equals(Object object)
>>> {
>>> // TODO: Warning - this method won't work in the case the id
>>> fields are not set
>>> if (!(object instanceof ArticleGroup)) {
>>> return false;
>>> }
>>> ArticleGroup other = (ArticleGroup)object;
>>> // If both are the same object, return true
>>> if(this == other)
>>> {
>>> return true;
>>> }
>>> // If both objects have ids, compare their ids
>>> if(this.getId() != null && other.getId() != null)
>>> {
>>> // If their ids are equal, return true
>>> if(this.getId().equals(other.getId()))
>>> {
>>> return true;
>>> }
>>> // Otherwise, return false
>>> else
>>> {
>>> return false;
>>> }
>>> }
>>> // If one or both do not have ids, compare their 'natural keys'
>>> if(this.getName() != null && this.getName().equals(other.getName())
>>> )
>>> {
>>> return true;
>>> }
>>> return false;
>>> }
>>>
>>> /**
>>> * Returns a string representation of the object. This
>>> implementation constructs * that representation based on the id
>>> fields.
>>> * @return a string representation of the object.
>>> */
>>> @Override
>>> public String toString()
>>> {
>>> return "com.acadept.model.ArticleGroup[id=" + getId() + "]";
>>> }
>>>
>>> public static Logger getLogger()
>>> {
>>> return logger;
>>> }
>>>
>>> public static void setLogger(Logger aLogger)
>>> {
>>> logger = aLogger;
>>> }
>>>
>>> public String getName()
>>> {
>>> return name;
>>> }
>>>
>>> public void setName(String name)
>>> {
>>> this.name = name;
>>> }
>>>
>>> public String getDescription()
>>> {
>>> return description;
>>> }
>>>
>>> public void setDescription(String description)
>>> {
>>> this.description = description;
>>> }
>>>
>>> public List<ArticlePlacement> getArticlePlacements()
>>> {
>>> return articlePlacements;
>>> }
>>>
>>> public void setArticlePlacements(List<ArticlePlacement>
>>> articlePlacements)
>>> {
>>> this.articlePlacements = articlePlacements;
>>> }
>>>
>>> public void addArticlePlacement(ArticlePlacement articlePlacement)
>>> {
>>> if(this.getArticlePlacements().contains(articlePlacement))
>>> {
>>> return;
>>> }
>>> getArticlePlacements().add(articlePlacement);
>>> articlePlacement.setArticleGroup(this);
>>> }
>>>
>>> public void removeArticlePlacement(ArticlePlacement articlePlacement)
>>> {
>>> getArticlePlacements().remove(articlePlacement);
>>> articlePlacement.setArticleGroup(null);
>>> }
>>> }
>>>
>>>
>>>> Thanks,
>>>>
>>>> -- markus.
>>>>
>>>> Greg Ederer wrote:
>>>>> Markus Fuchs wrote:
>>>>>> Hi Greg,
>>>>>>
>>>>>> Do you get a foreign key violation w/o using @PreRemove callbacks
>>>>>> in your pojos? Are you using a current glassfish build?
>>>>>>
>>>>> Hi Markus,
>>>>>
>>>>> Yes. When I em.remove() an ArticlePlacement without the
>>>>> @PreRemove, I get a PSQLException (I'm using PostgreSQL) with a
>>>>> foreign key constraint violation message.
>>>>>
>>>>> I'm using v2b50.
>>>>>
>>>>> Thanks for the reply.
>>>>>
>>>>> Cheers,
>>>>>
>>>>> Greg
>>>>>> Thanks,
>>>>>>
>>>>>> -- markus.
>>>>>>
>>>>>> Greg Ederer wrote:
>>>>>>> I managed to get this working by adding the following to Article:
>>>>>>>
>>>>>>> @PreRemove
>>>>>>> public void beforeRemove()
>>>>>>> {
>>>>>>> List<ArticlePlacement> articlePlacements =
>>>>>>> getArticlePlacements();
>>>>>>> for(ArticlePlacement ap : articlePlacements)
>>>>>>> {
>>>>>>> ap.setArticle(null);
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> And in ArticlePlacement:
>>>>>>>
>>>>>>> @PreRemove
>>>>>>> public void beforeRemove()
>>>>>>> {
>>>>>>> getArticleGroup().removeArticlePlacement(this);
>>>>>>> if(getArticle() != null)
>>>>>>> {
>>>>>>> getArticle().removeArticlePlacement(this);
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> I have a feeling this is not the best way to handle this (and,
>>>>>>> I'm guessing that I'll feel like a dummy when I find out the
>>>>>>> correct way to do this, because it will be pretty obvious).
>>>>>>>
>>>>>>> Any advice welcome.
>>>>>>>
>>>>>>> Cheers,
>>>>>>>
>>>>>>> Greg
>>>>>>>
>>>>>>> Greg Ederer wrote:
>>>>>>>> Oops! Accidentally hit send. Please ignore previous post.
>>>>>>>>
>>>>>>>> I have a model containing three entity classes: Article,
>>>>>>>> ArticleGroup and ArticlePlacement. An ArticleGroup contains
>>>>>>>> zero or more ArticlePlacement objects. Each ArticlePlacement
>>>>>>>> wraps an Article (ArticlePlacement also has a start run date
>>>>>>>> and an end run date, which allows me to run an article in
>>>>>>>> multiple groups during different periods).
>>>>>>>>
>>>>>>>> So, in Article, I have:
>>>>>>>>
>>>>>>>> @OneToMany(mappedBy = "article", cascade=CascadeType.ALL)
>>>>>>>> private List<ArticlePlacement> articlePlacements = new
>>>>>>>> ArrayList<ArticlePlacement>();
>>>>>>>>
>>>>>>>> In ArticleGroup, I have:
>>>>>>>>
>>>>>>>> @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE,
>>>>>>>> CascadeType.REFRESH})
>>>>>>>> @OrderBy("position ASC")
>>>>>>>> private List<ArticlePlacement> articlePlacements = new
>>>>>>>> ArrayList<ArticlePlacement>();
>>>>>>>>
>>>>>>>> And, in ArticlePlacement, I have:
>>>>>>>>
>>>>>>>> @ManyToOne
>>>>>>>> private Article article;
>>>>>>>>
>>>>>>>> @ManyToOne
>>>>>>>> private ArticleGroup articleGroup;
>>>>>>>>
>>>>>>>> @PreRemove
>>>>>>>> public void beforeRemove()
>>>>>>>> {
>>>>>>>> getArticleGroup().removeArticlePlacement(this);
>>>>>>>> getArticle().removeArticlePlacement(this);
>>>>>>>> }
>>>>>>>>
>>>>>>>> When I EntityManager.remove() an Article, I get a
>>>>>>>> java.util.ConcurrentModificationException due to the
>>>>>>>> getArticle().removeArticlePlacement(this) in @PreRemove,
>>>>>>>> above. But, if I comment this out, I get a "violates foreign
>>>>>>>> key" PSQLException.
>>>>>>>>
>>>>>>>> Can someone tell me how to deal with this situation correctly?
>>>>>>>>
>>>>>>>> Thanks!
>>>>>>>>
>>>>>>>> Greg
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>
>>>>>
>>>
>>>
>>
>>


-- 
| E R G O N O S I S
| Greg Ederer
| Lead Developer
| greg_at_ergonosis.com
| 360.774.6848
|