From da7fdf984534cefb5ae32fd13f9cd50a8b6313a8 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Wed, 8 Mar 2017 17:37:12 +0100 Subject: [PATCH] [Bug #2] Fixed most of the merging issues. --- .../cvut/kbss/jopa/sessions/CloneBuilder.java | 15 +++++-- .../kbss/jopa/model/EntityManagerImpl.java | 35 +++++++---------- .../model/OneLevelMergeCascadeExplorer.java | 39 +++++++++++++++++++ .../kbss/jopa/sessions/CloneBuilderImpl.java | 9 ++++- .../kbss/jopa/sessions/UnitOfWorkImpl.java | 34 ++++++++++------ .../kbss/jopa/sessions/UnitOfWorkTest.java | 15 ++++++- .../environment/TestEnvironmentUtils.java | 11 +++--- .../CreateOperationsMultiContextRunner.java | 24 ++++-------- .../test/runner/CreateOperationsRunner.java | 2 + .../test/runner/DeleteOperationsRunner.java | 18 ++++----- .../test/runner/UpdateOperationsRunner.java | 4 +- ...UpdateOperationsWithInheritanceRunner.java | 8 ++-- .../cz/cvut/kbss/jopa/owl2java/Constants.java | 2 +- 13 files changed, 137 insertions(+), 79 deletions(-) create mode 100644 jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/OneLevelMergeCascadeExplorer.java diff --git a/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/CloneBuilder.java b/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/CloneBuilder.java index 796875af5..22a6a4ec6 100644 --- a/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/CloneBuilder.java +++ b/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/CloneBuilder.java @@ -53,12 +53,21 @@ Object buildClone(Object cloneOwner, Field clonedField, Object original, Descriptor descriptor); /** - * Resets the clone builder. Especially resets the visited objects cache to - * make sure all the clones are built from scratch and are not affected by - * the previously built ones. + * Resets the clone builder. + *

+ * Especially resets the visited objects cache to make sure all the clones are built from scratch and are not + * affected by the previously built ones. */ void reset(); + /** + * Removes the specified instance from the clone builder's visited entities cache. + * + * @param instance The instance to remove (original object). + * @param descriptor Instance descriptor + */ + void removeVisited(Object instance, Descriptor descriptor); + /** * Merges the changes on clone into the original object. * diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/EntityManagerImpl.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/EntityManagerImpl.java index 8c339c9be..f86f59e19 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/EntityManagerImpl.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/EntityManagerImpl.java @@ -160,30 +160,25 @@ private T mergeInternal(final T entity, final Descriptor descriptor) { switch (getState(entity, descriptor)) { case MANAGED_NEW: case MANAGED: - new OneLevelCascadeExplorer() { + new OneLevelMergeCascadeExplorer() { @Override - protected void exploreCascaded(Attribute at, Object o) { - mergeX(at, o, descriptor); + protected void exploreCascaded(Attribute at, Object merged, Object toMerge) { + final Descriptor attDescriptor = descriptor.getAttributeDescriptor(at); + mergeX(at, merged, toMerge, attDescriptor); } - }.start(this, entity, CascadeType.MERGE); + }.start(this, entity, entity); return entity; case NOT_MANAGED: final T merged; merged = getCurrentPersistenceContext().mergeDetached(entity, descriptor); - new OneLevelCascadeExplorer() { + new OneLevelMergeCascadeExplorer() { @Override - protected void exploreCascaded(Attribute at, Object o) { + protected void exploreCascaded(Attribute at, Object merged, Object toMerge) { final Descriptor attDescriptor = descriptor.getAttributeDescriptor(at); - mergeX(at, o, attDescriptor); - } - - @Override - protected void exploreNonCascaded(Attribute at, Object o) { - final Object attVal = EntityPropertiesUtils.getAttributeValue(at, o); - EntityPropertiesUtils.setFieldValue(at.getJavaField(), o, attVal); + mergeX(at, merged, toMerge, attDescriptor); } - }.start(this, merged, CascadeType.MERGE); + }.start(this, merged, entity); return merged; case REMOVED: default: @@ -191,22 +186,22 @@ protected void exploreNonCascaded(Attribute at, Object o) { } } - private void mergeX(Attribute at, Object o, Descriptor descriptor) { - Object attVal = EntityPropertiesUtils.getAttributeValue(at, o); + private void mergeX(Attribute at, Object merged, Object toMerge, Descriptor descriptor) { + Object attVal = EntityPropertiesUtils.getAttributeValue(at, toMerge); if (attVal == null) { return; } if (at.isCollection()) { Collection c = (Collection) attVal; - Collection merged = CollectionFactory.createInstance(c); + Collection result = CollectionFactory.createInstance(c); for (final Object ox2 : c) { - merged.add(mergeInternal(ox2, descriptor)); + result.add(mergeInternal(ox2, descriptor)); } - attVal = getCurrentPersistenceContext().createIndirectCollection(merged, o, at.getJavaField()); + attVal = getCurrentPersistenceContext().createIndirectCollection(result, merged, at.getJavaField()); } else { attVal = mergeInternal(attVal, descriptor); } - EntityPropertiesUtils.setFieldValue(at.getJavaField(), o, attVal); + EntityPropertiesUtils.setFieldValue(at.getJavaField(), merged, attVal); } @Override diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/OneLevelMergeCascadeExplorer.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/OneLevelMergeCascadeExplorer.java new file mode 100644 index 000000000..986e35d9b --- /dev/null +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/model/OneLevelMergeCascadeExplorer.java @@ -0,0 +1,39 @@ +package cz.cvut.kbss.jopa.model; + +import cz.cvut.kbss.jopa.exceptions.OWLPersistenceException; +import cz.cvut.kbss.jopa.model.annotations.CascadeType; +import cz.cvut.kbss.jopa.model.metamodel.Attribute; +import cz.cvut.kbss.jopa.model.metamodel.EntityType; + +import java.util.Arrays; +import java.util.List; + +/** + * Merge cascade resolver. + *

+ * Cascades the merge operation to attributes which support merge cascading. + */ +class OneLevelMergeCascadeExplorer { + + void start(final AbstractEntityManager pc, final Object merged, final Object toMerge) { + + final EntityType a = pc.getMetamodel().entity(toMerge.getClass()); + for (final Attribute at : a.getAttributes()) { + + final List cTypes = Arrays.asList(at.getCascadeTypes()); + + try { + if (cTypes.contains(CascadeType.ALL) || cTypes.contains(CascadeType.MERGE)) { + exploreCascaded(at, merged, toMerge); + } + } catch (Exception e) { + throw new OWLPersistenceException(e); + } + } + } + + void exploreCascaded(final Attribute at, final Object merged, final Object toMerge) + throws IllegalAccessException { + // empty body + } +} diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/sessions/CloneBuilderImpl.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/sessions/CloneBuilderImpl.java index 979b8bbf1..5eac08043 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/sessions/CloneBuilderImpl.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/sessions/CloneBuilderImpl.java @@ -1,11 +1,11 @@ /** * Copyright (C) 2016 Czech Technical University in Prague - * + *

* This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any * later version. - * + *

* This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more @@ -226,6 +226,11 @@ public void reset() { visitedEntities.clear(); } + @Override + public void removeVisited(Object instance, Descriptor descriptor) { + visitedEntities.remove(descriptor, instance); + } + IndirectCollection createIndirectCollection(Object c, Object owner, Field f) { return uow.createIndirectCollection(c, owner, f); } diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/sessions/UnitOfWorkImpl.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/sessions/UnitOfWorkImpl.java index a6868396e..a744c5a18 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/sessions/UnitOfWorkImpl.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/sessions/UnitOfWorkImpl.java @@ -597,11 +597,12 @@ private T mergeDetachedInternal(T entity, Descriptor descriptor) { if (chSet.hasChanges()) { lifecycleListenerCaller.invokePreUpdateListeners(et, entity); } -// for (ChangeRecord record : chSet.getChanges().values()) { -// final Field field = et.getFieldSpecification(record.getAttributeName()).getJavaField(); -// storage.merge(entity, field, descriptor); -// } - // TODO Merge changes (it will also cause change propagation into the storage) + for (ChangeRecord record : chSet.getChanges().values()) { + final Field field = et.getFieldSpecification(record.getAttributeName()).getJavaField(); + storage.merge(entity, field, descriptor); + } + final DetachedInstanceMerger merger = new DetachedInstanceMerger(this); + merger.mergeChangesFromDetachedToManagedInstance(chSet, descriptor); if (chSet.hasChanges()) { lifecycleListenerCaller.invokePostUpdateListeners(et, entity); } @@ -620,9 +621,6 @@ private T mergeDetachedInternal(T entity, Descriptor descriptor) { return et.getJavaType().cast(clone); } - /** - * {@inheritDoc} - */ @Override void registerEntityWithPersistenceContext(Object entity, UnitOfWorkImpl uow) { parent.registerEntityWithPersistenceContext(entity, uow); @@ -729,9 +727,7 @@ private void registerNewObjectInternal(Object entity, Descriptor descriptor) { if (id == null) { EntityPropertiesUtils.verifyIdentifierIsGenerated(entity, eType); } - if (isIndividualManaged(id, entity) && !entity.getClass().isEnum()) { - throw individualAlreadyManaged(id); - } + verifyCanPersist(id, entity, eType, descriptor); storage.persist(id, entity, descriptor); if (id == null) { // If the ID was null, extract it from the entity. It is present now @@ -748,6 +744,16 @@ private void registerNewObjectInternal(Object entity, Descriptor descriptor) { lifecycleListenerCaller.invokePostPersistListeners(eType, entity); } + private void verifyCanPersist(Object id, Object instance, EntityType et, Descriptor descriptor) { + if (isIndividualManaged(id, instance) && !instance.getClass().isEnum()) { + throw individualAlreadyManaged(id); + } + if (storage.contains(id, instance.getClass(), descriptor)) { + throw new OWLEntityExistsException( + "Individual " + id + " of type " + et.getIRI() + " already exists in storage."); + } + } + private boolean isIndividualManaged(Object identifier, Object entity) { return keysToClones.containsKey(identifier) || newObjectsKeyToClone.containsKey(identifier) && !cloneMapping.containsKey(entity); @@ -790,7 +796,8 @@ public void unregisterObject(Object object) { return; } cloneMapping.remove(object); - cloneToOriginals.remove(object); + final Object original = cloneToOriginals.remove(object); + keysToClones.remove(EntityPropertiesUtils.getPrimaryKey(object, getMetamodel())); getDeletedObjects().remove(object); if (hasNew) { @@ -799,6 +806,9 @@ public void unregisterObject(Object object) { getNewObjectsOriginalToClone().remove(newOriginal); } } + if (original != null) { + cloneBuilder.removeVisited(original, repoMap.getEntityDescriptor(object)); + } unregisterObjectFromPersistenceContext(object); } diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/sessions/UnitOfWorkTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/sessions/UnitOfWorkTest.java index d9d8f475a..95e0f3fbe 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/sessions/UnitOfWorkTest.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/sessions/UnitOfWorkTest.java @@ -71,6 +71,8 @@ public class UnitOfWorkTest { private ServerSessionStub serverSessionStub; + private CloneBuilder cloneBuilder; + private UnitOfWorkImpl uow; @BeforeClass @@ -93,6 +95,10 @@ public void setUp() throws Exception { final Field connectionField = UnitOfWorkImpl.class.getDeclaredField("storage"); connectionField.setAccessible(true); connectionField.set(uow, storageMock); + final Field cbField = UnitOfWorkImpl.class.getDeclaredField("cloneBuilder"); + cbField.setAccessible(true); + this.cloneBuilder = spy((CloneBuilder) cbField.get(uow)); + cbField.set(uow, cloneBuilder); initEntities(); } @@ -443,10 +449,17 @@ public void testRemoveObjectNotRegistered() { public void testUnregisterObject() { final OWLClassA managed = (OWLClassA) uow.registerExistingObject(entityA, descriptor); assertTrue(uow.contains(managed)); - this.uow.unregisterObject(managed); + uow.unregisterObject(managed); assertFalse(uow.contains(managed)); } + @Test + public void unregisterObjectRemovesItFromCloneBuilderCache() { + final OWLClassA managed = (OWLClassA) uow.registerExistingObject(entityA, descriptor); + uow.unregisterObject(managed); + verify(cloneBuilder).removeVisited(entityA, descriptor); + } + @Test public void testRevertObject() { final OWLClassA managed = (OWLClassA) uow.registerExistingObject(entityA, descriptor); diff --git a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/environment/TestEnvironmentUtils.java b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/environment/TestEnvironmentUtils.java index 78653efac..9447f8141 100644 --- a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/environment/TestEnvironmentUtils.java +++ b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/environment/TestEnvironmentUtils.java @@ -1,11 +1,11 @@ /** * Copyright (C) 2016 Czech Technical University in Prague - * + *

* This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any * later version. - * + *

* This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more @@ -19,16 +19,15 @@ public class TestEnvironmentUtils { - public static boolean arePropertiesEqual(Map> pOne, - Map> pTwo) { + public static boolean arePropertiesEqual(Map> pOne, Map> pTwo) { if (pOne.size() != pTwo.size()) { return false; } - for (Map.Entry> e : pOne.entrySet()) { + for (Map.Entry> e : pOne.entrySet()) { if (!pTwo.containsKey(e.getKey())) { return false; } - final Set set = pTwo.get(e.getKey()); + final Set set = pTwo.get(e.getKey()); if (!e.getValue().equals(set)) { return false; } diff --git a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/CreateOperationsMultiContextRunner.java b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/CreateOperationsMultiContextRunner.java index e13196ba0..f0f202f3c 100644 --- a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/CreateOperationsMultiContextRunner.java +++ b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/CreateOperationsMultiContextRunner.java @@ -1,11 +1,11 @@ /** * Copyright (C) 2016 Czech Technical University in Prague - * + *

* This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any * later version. - * + *

* This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more @@ -14,6 +14,7 @@ */ package cz.cvut.kbss.jopa.test.runner; +import cz.cvut.kbss.jopa.exceptions.OWLEntityExistsException; import cz.cvut.kbss.jopa.model.descriptors.Descriptor; import cz.cvut.kbss.jopa.model.descriptors.EntityDescriptor; import cz.cvut.kbss.jopa.model.descriptors.ObjectPropertyCollectionDescriptor; @@ -47,7 +48,6 @@ private void initialize() { @Test public void testPersistDataPropertyIntoContext() throws Exception { - logger.debug("Test: persist an entity into the default context and its data property into a different one."); this.em = getEntityManager("MultiPersistDataPropertyIntoContext", false); final Descriptor aDescriptor = new EntityDescriptor(); aDescriptor.addAttributeContext(OWLClassA.class.getDeclaredField("stringAttribute"), CONTEXT_ONE); @@ -65,8 +65,6 @@ public void testPersistDataPropertyIntoContext() throws Exception { @Test public void testPersistObjectPropertyIntoContext() throws Exception { - logger.debug( - "Test: persist entity into one context and its object property into another, along with its own attributes."); this.em = getEntityManager("MultiPersistObjectPropertyIntoContext", false); final Descriptor dDescriptor = new EntityDescriptor(); final Descriptor aDescriptor = new EntityDescriptor(CONTEXT_ONE); @@ -88,7 +86,6 @@ public void testPersistObjectPropertyIntoContext() throws Exception { @Test public void testPersistWithGeneratedIntoContext() { - logger.debug("Test: persist entity with generated ID into a context."); this.em = getEntityManager("MultiPersistWithGeneratedIntoContext", false); final Descriptor eDescriptor = new EntityDescriptor(CONTEXT_ONE); em.getTransaction().begin(); @@ -120,10 +117,9 @@ public void testPersistReferenceIntoContextAndThenOwnerIntoDefault() { assertNotNull(res.getOwlClassA()); } - @Test - public void persistTwiceIntoSameContextIsLegal() { + @Test(expected = OWLEntityExistsException.class) + public void persistTwiceIntoSameContextIsInvalid() { this.em = getEntityManager("MultiPersistTwiceIntoOneContext", false); - logger.debug("Test: persist an entity twice into the same context."); final Descriptor aDescriptor = new EntityDescriptor(CONTEXT_ONE); em.getTransaction().begin(); em.persist(entityA, aDescriptor); @@ -132,13 +128,11 @@ public void persistTwiceIntoSameContextIsLegal() { em.getTransaction().begin(); em.persist(entityA, aDescriptor); em.getTransaction().commit(); - assertNotNull(em.find(OWLClassA.class, entityA.getUri(), aDescriptor)); } @Test public void persistTwiceIntoDifferentContextsIsLegal() { this.em = getEntityManager("MultiPersistTwiceIntoDifferentContexts", false); - logger.debug("Test: persist an entity into two different contexts."); final Descriptor aDescriptorOne = new EntityDescriptor(CONTEXT_ONE); final Descriptor aDescriptorTwo = new EntityDescriptor(CONTEXT_TWO); em.getTransaction().begin(); @@ -158,7 +152,6 @@ public void persistTwiceIntoDifferentContextsIsLegal() { @Test public void testPersistPropertiesIntoDifferentContext() throws Exception { this.em = getEntityManager("MultiPersistPropertiesIntoDifferentContext", false); - logger.debug("Test: persist an entity and persist its properties into a different context."); final Descriptor bDescriptor = new EntityDescriptor(); entityB.setProperties(Generators.createProperties(10)); bDescriptor.addAttributeContext(OWLClassB.class.getDeclaredField("properties"), CONTEXT_ONE); @@ -179,7 +172,6 @@ public void testPersistPropertiesIntoDifferentContext() throws Exception { @Test public void testPersistCascadeIntoThreeContexts() throws Exception { this.em = getEntityManager("MultiPersistCascadeIntoThreeContexts", false); - logger.debug("Test: persist three entities in cascaded relationship, each into a different context."); final Descriptor gDescriptor = new EntityDescriptor(); final Descriptor hDescriptor = new EntityDescriptor(CONTEXT_ONE); final Descriptor aDescriptor = new EntityDescriptor(CONTEXT_TWO); @@ -204,8 +196,6 @@ public void testPersistCascadeIntoThreeContexts() throws Exception { @Test public void testPersistSetWithAttributeContexts() throws Exception { - logger.debug( - "Test: persist entity with simple set, the set will be in a different context and attributes of its element in another."); this.em = getEntityManager("MultiPersistSetWithAttributeContexts", false); entityF.setSimpleSet(Generators.createSimpleSet(20)); final Descriptor fDescriptor = new EntityDescriptor(); @@ -235,8 +225,8 @@ public void testPersistSetWithAttributeContexts() throws Exception { @Test public void testPersistEntityWithObjectPropertyWithGeneratedIdentifierAndPutTheReferenceIntoContext() throws Exception { - logger.debug("Test: persist entity with reference to an entity with generated identifier. " - + "The identifier should be generated automatically before the referenced entity itself is persisted."); + // persist entity with reference to an entity with generated identifier. + // The identifier should be generated automatically before the referenced entity itself is persisted. this.em = getEntityManager("PersistEntityWithObjectPropertyWithGeneratedIdentifierContexts", true); entityK.setOwlClassE(entityE); assertNull(entityE.getUri()); diff --git a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/CreateOperationsRunner.java b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/CreateOperationsRunner.java index 52e2a9db8..cbbc140f4 100644 --- a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/CreateOperationsRunner.java +++ b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/CreateOperationsRunner.java @@ -120,8 +120,10 @@ public void persistingDetachedEntityIsIllegal() { final OWLClassA det = em.find(OWLClassA.class, entityA.getUri()); assertNotNull(det); + em.getTransaction().begin(); em.detach(det); em.persist(det); + em.getTransaction().commit(); } @Test diff --git a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/DeleteOperationsRunner.java b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/DeleteOperationsRunner.java index da5fdc45f..ee35acdf5 100644 --- a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/DeleteOperationsRunner.java +++ b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/DeleteOperationsRunner.java @@ -1,11 +1,11 @@ /** * Copyright (C) 2016 Czech Technical University in Prague - * + *

* This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any * later version. - * + *

* This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more @@ -20,6 +20,7 @@ import cz.cvut.kbss.jopa.model.annotations.OWLObjectProperty; import cz.cvut.kbss.jopa.test.*; import cz.cvut.kbss.jopa.test.environment.Generators; +import cz.cvut.kbss.jopa.test.environment.TestEnvironmentUtils; import cz.cvut.kbss.jopa.utils.EntityPropertiesUtils; import org.junit.Ignore; import org.junit.Test; @@ -362,13 +363,7 @@ public void testRemoveTypedUnmappedPropertyValue() { } } em.getTransaction().commit(); - final Iterator it = toUpdate.getProperties().keySet().iterator(); - while (it.hasNext()) { - final URI property = it.next(); - if (toUpdate.getProperties().get(property).isEmpty()) { - it.remove(); - } - } + toUpdate.getProperties().keySet().removeIf(property -> toUpdate.getProperties().get(property).isEmpty()); if (toUpdate.getProperties().isEmpty()) { toUpdate.setProperties(null); } @@ -390,11 +385,12 @@ public void testRemoveAllValuesOfTypedUnmappedProperty() { keys.stream().filter(k -> Generators.randomBoolean()) .forEach(key -> toUpdate.getProperties().remove(key)); em.getTransaction().begin(); - em.merge(toUpdate); + final OWLClassP merged = em.merge(toUpdate); + assertTrue(TestEnvironmentUtils.arePropertiesEqual(toUpdate.getProperties(), merged.getProperties())); em.getTransaction().commit(); final OWLClassP res = em.find(OWLClassP.class, entityP.getUri()); - assertEquals(toUpdate.getProperties(), res.getProperties()); + assertTrue(TestEnvironmentUtils.arePropertiesEqual(toUpdate.getProperties(), res.getProperties())); } @Test diff --git a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/UpdateOperationsRunner.java b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/UpdateOperationsRunner.java index ec1c209f4..56c19db80 100644 --- a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/UpdateOperationsRunner.java +++ b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/UpdateOperationsRunner.java @@ -143,8 +143,8 @@ public void testUpdateReference() { } @Test - public void testMergeSet() throws Exception { - logger.debug("Test: merge set property."); + public void mergedInstanceWithChangesInCascadedPluralReferenceAttributeContainsUpdatedValues() + throws Exception { this.em = getEntityManager("MergeSet", false); persist(entityJ); em.clear(); diff --git a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/UpdateOperationsWithInheritanceRunner.java b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/UpdateOperationsWithInheritanceRunner.java index 5a0220a85..8dd99c50f 100644 --- a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/UpdateOperationsWithInheritanceRunner.java +++ b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/runner/UpdateOperationsWithInheritanceRunner.java @@ -1,11 +1,11 @@ /** * Copyright (C) 2016 Czech Technical University in Prague - * + *

* This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any * later version. - * + *

* This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more @@ -95,8 +95,8 @@ public void testUpdateDataPropertyInEntitySuperclass() { entityT.setIntAttribute(newInt); final String newDescription = "new entity description"; em.getTransaction().begin(); - em.merge(entityT); - entityT.setDescription(newDescription); + final OWLClassT merged = em.merge(entityT); + merged.setDescription(newDescription); em.getTransaction().commit(); final OWLClassT result = em.find(OWLClassT.class, entityT.getUri()); diff --git a/jopa-owl2java/src/main/java/cz/cvut/kbss/jopa/owl2java/Constants.java b/jopa-owl2java/src/main/java/cz/cvut/kbss/jopa/owl2java/Constants.java index 512d26213..096e5f57c 100644 --- a/jopa-owl2java/src/main/java/cz/cvut/kbss/jopa/owl2java/Constants.java +++ b/jopa-owl2java/src/main/java/cz/cvut/kbss/jopa/owl2java/Constants.java @@ -34,7 +34,7 @@ public class Constants { /** * Tool version. */ - public static final String VERSION = "$VERSION$"; + public static final String VERSION = "0.9.3"; private Constants() {