diff options
2 files changed, 102 insertions, 6 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_338884_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_338884_Test.java index ac30518ba2..83be399d5c 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_338884_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_338884_Test.java @@ -14,16 +14,21 @@ import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.tests.AbstractCDOTest; import org.eclipse.emf.cdo.tests.model4.ContainedElementNoOpposite; +import org.eclipse.emf.cdo.tests.model4.RefMultiContainedNPL; import org.eclipse.emf.cdo.tests.model4.RefMultiNonContainedNPL; +import org.eclipse.emf.cdo.tests.model4.RefSingleContainedNPL; import org.eclipse.emf.cdo.tests.model4.RefSingleNonContainedNPL; import org.eclipse.emf.cdo.tests.model4.model4Factory; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CommitException; import org.eclipse.emf.cdo.util.CommitIntegrityException; +import org.eclipse.net4j.util.transaction.TransactionException; + import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -161,4 +166,80 @@ public class Bugzilla_338884_Test extends AbstractCDOTest session.close(); } + + public void test_nonBidiMultiRef_newTarget() throws CommitException + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + + model4Factory factory = getModel4Factory(); + + CDOResource resource = transaction.createResource(getResourcePath("test")); + transaction.commit(); + + RefMultiContainedNPL parent = factory.createRefMultiContainedNPL(); + resource.getContents().add(parent); + + ContainedElementNoOpposite child = factory.createContainedElementNoOpposite(); + parent.getElements().add(child); + + transaction.setCommittables(new HashSet<EObject>(Arrays.asList(new EObject[] { resource, parent }))); + try + { + transaction.commit(); + fail("Should have thrown an exception"); + } + catch (CommitException e) + { + Throwable c = e.getCause(); + if (c instanceof TransactionException && c.getCause() instanceof CommitIntegrityException) + { + // Good + } + else + { + throw e; + } + } + + session.close(); + } + + public void test_nonBidiSingleRef_newTarget() throws CommitException + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + + model4Factory factory = getModel4Factory(); + + CDOResource resource = transaction.createResource(getResourcePath("test")); + transaction.commit(); + + RefSingleContainedNPL parent = factory.createRefSingleContainedNPL(); + resource.getContents().add(parent); + + ContainedElementNoOpposite child = factory.createContainedElementNoOpposite(); + parent.setElement(child); + + transaction.setCommittables(new HashSet<EObject>(Arrays.asList(new EObject[] { resource, parent }))); + try + { + transaction.commit(); + fail("Should have thrown an exception"); + } + catch (CommitException e) + { + Throwable c = e.getCause(); + if (c instanceof TransactionException && c.getCause() instanceof CommitIntegrityException) + { + // Good + } + else + { + throw e; + } + } + + session.close(); + } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java index cd534f1b5e..048094973f 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java @@ -86,7 +86,7 @@ public class CommitIntegrityCheck { CDOObject newObject = transaction.getObject(newID); checkContainerIncluded(newObject, "new"); - checkCurrentBidiRefTargetsIncluded(newObject, "new"); + checkCurrentRefTargetsIncluded(newObject, "new"); } // For detached objects: ensure that their former container is included, @@ -338,18 +338,18 @@ public class CommitIntegrityCheck } } - private void checkCurrentBidiRefTargetsIncluded(CDOObject referencer, String msgFrag) throws CommitIntegrityException + private void checkCurrentRefTargetsIncluded(CDOObject referencer, String msgFrag) throws CommitIntegrityException { for (EReference eRef : referencer.eClass().getEAllReferences()) { - if (EMFUtil.isPersistent(eRef) && hasPersistentOpposite(eRef)) + if (EMFUtil.isPersistent(eRef)) { if (eRef.isMany()) { EList<?> list = (EList<?>)referencer.eGet(eRef); - for (Object element : list) + for (Object refTarget : list) { - checkBidiRefTargetIncluded(element, referencer, eRef.getName(), msgFrag); + checkBidiRefTargetOrNewNonBidiTargetIncluded(referencer, eRef, refTarget, msgFrag); } } else @@ -357,13 +357,28 @@ public class CommitIntegrityCheck Object refTarget = referencer.eGet(eRef); if (refTarget != null) { - checkBidiRefTargetIncluded(refTarget, referencer, eRef.getName(), msgFrag); + checkBidiRefTargetOrNewNonBidiTargetIncluded(referencer, eRef, refTarget, msgFrag); } } } } } + private void checkBidiRefTargetOrNewNonBidiTargetIncluded(CDOObject referencer, EReference eRef, Object refTarget, + String msgFrag) throws CommitIntegrityException + { + if (hasPersistentOpposite(eRef)) + { + // It's a bi-di ref; the target must definitely be included + checkBidiRefTargetIncluded(refTarget, referencer, eRef.getName(), msgFrag); + } + else if (isNew(refTarget)) + { + // It's a non-bidi ref; the target doesn't have to be included unless it's NEW + checkIncluded(refTarget, "target of reference '" + eRef.getName() + "' of " + msgFrag, referencer); + } + } + private void checkFormerBidiRefTargetsIncluded(CDOObject referencer, String msgFrag) throws CommitIntegrityException { // The referencer argument should really be a detached object, and so we know |