JPA: Cascade.REMOVE not working for unidirectional OneToMany-Relationship

View: New views
3 Messages — Rating Filter:   Alert me  

JPA: Cascade.REMOVE not working for unidirectional OneToMany-Relationship

by zebhed :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I have justed switched from Toplink Essentials to EclipseLink.
I am using Glassfish v2, JPA and MySQL 5.

So far, almost everything seems to work fine.

But Cascade.REMOVE does not work for unidirectional OneToMany-Relationships that are associated via a JoinTable.

Example:
--------
[User Entity] 1 --------> N [Invitation Entity]

Now, when passing a user entity to the remove() method of the EntityManager I get the following exception:

[#|2008-07-21T19:46:56.939+0200|WARNING|sun-appserver9.1|org.eclipse.persistence.session.file:/C:/Programme/Sun/SDK/domains/domain1/applications/j2ee-apps/war/war-ejb_jar/-war-ejbPU|_ThreadID=18;_ThreadName=httpSSLWorkerThread-8080-1;_RequestID=8e614318-51e6-483b-9c21-14ba2326e340;|
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 1.0 (Build 1.0 - 20080707)): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`war_db/lkp_users_invitations`, CONSTRAINT `FK_lkp_users_invitations__invitation_id` FOREIGN KEY (`_invitation_id`) REFERENCES `invitations` (`_id`))
Error Code: 1451
Call: DELETE FROM invitations WHERE (_id = ?)
        bind => [1000]
Query: DeleteObjectQuery(com.war.bus.data.entity.Invitation@43f)
        at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:313)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:757)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:823)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:557)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:500)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeCall(AbstractSession.java:855)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:204)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:190)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.deleteObject(DatasourceCallQueryMechanism.java:181)
        at org.eclipse.persistence.internal.queries.StatementQueryMechanism.deleteObject(StatementQueryMechanism.java:102)
        at org.eclipse.persistence.queries.DeleteObjectQuery.executeDatabaseQuery(DeleteObjectQuery.java:168)
        at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:666)
        at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:585)
        at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:114)
        at org.eclipse.persistence.queries.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:113)
        at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:86)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2588)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1178)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1162)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1108)
        at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:326)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1245)
        at org.eclipse.persistence.internal.jpa.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:482)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1331)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:2849)
        at org.eclipse.persistence.internal.jpa.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:227)
        at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:157)
        at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68)
        at com.sun.enterprise.distributedtx.J2EETransaction.commit(J2EETransaction.java:419)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:371)
//.... rest of stacktrace

For me, it seems that EclipseLink does not remove the rows from the join table when deleting the entities that are affected by Cascade.REMOVE.

I have several unidirectional OneToMany relationships marked with Cascade.REMOVE in my app. They all share this problem.

I also want to make clear that my app worked perfectly when I was using Toplink Essentials. I have not made any changes to the source code of my app except ...

The only things I changed were:
- copied "eclipselink.jar" to domain1\lib
- altered "persistence.xml"

My persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd">
        <persistence-unit name="war-ejbPU" transaction-type="JTA">
                <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
                <jta-data-source>jdbc/WarConnectionPool</jta-data-source>
                <properties>
                        <property name="eclipselink.target-server" value="SunAS9"/>
                        <property name="eclipselink.ddl-generation" value="create-tables"/>
                        <property name="eclipselink.ddl-generation.output-mode" value="database"/>
                        <property name="eclipselink.logging.level" value="finest"/>
                </properties>
        </persistence-unit>
</persistence>

Maybe someone can give me a hint why I am running into this problem (or is it a bug?).

Re: JPA: Cascade.REMOVE not working for unidirectional OneToMany-Relationship

by zebhed :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Re: JPA: Cascade.REMOVE not working for unidirectional OneToMany-Relationship

by James Sutherland :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I updated the bug with the details, and workarounds.

The best workaround is most likely to make the relationship @PrivateOwned until the bug is fixed.


zebhed wrote: