Skip to content

Method: removeWorksForInstanceRetrievedUsingGetReference()

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.jopa.test.runner;
19:
20: import cz.cvut.kbss.jopa.model.annotations.Id;
21: import cz.cvut.kbss.jopa.model.annotations.OWLAnnotationProperty;
22: import cz.cvut.kbss.jopa.model.annotations.OWLDataProperty;
23: import cz.cvut.kbss.jopa.model.annotations.OWLObjectProperty;
24: import cz.cvut.kbss.jopa.test.*;
25: import cz.cvut.kbss.jopa.test.environment.DataAccessor;
26: import cz.cvut.kbss.jopa.test.environment.Generators;
27: import cz.cvut.kbss.jopa.test.environment.PersistenceFactory;
28: import cz.cvut.kbss.jopa.test.environment.TestEnvironmentUtils;
29: import cz.cvut.kbss.jopa.utils.EntityPropertiesUtils;
30: import cz.cvut.kbss.jopa.vocabulary.DC;
31: import org.junit.jupiter.api.Disabled;
32: import org.junit.jupiter.api.Test;
33: import org.slf4j.Logger;
34:
35: import java.lang.reflect.Field;
36: import java.net.URI;
37: import java.util.*;
38: import java.util.stream.Collectors;
39: import java.util.stream.IntStream;
40:
41: import static org.hamcrest.MatcherAssert.assertThat;
42: import static org.hamcrest.Matchers.empty;
43: import static org.junit.jupiter.api.Assertions.*;
44:
45: public abstract class DeleteOperationsRunner extends BaseRunner {
46:
47: public DeleteOperationsRunner(Logger logger, PersistenceFactory persistenceFactory, DataAccessor dataAccessor) {
48: super(logger, persistenceFactory, dataAccessor);
49: }
50:
51: @Test
52: void testRemoveSimple() {
53: this.em = getEntityManager("SimpleRemove", false);
54: persist(entityA);
55:
56: final OWLClassA a = em.find(OWLClassA.class, entityA.getUri());
57: assertNotNull(a);
58: em.getTransaction().begin();
59: em.remove(a);
60: em.getTransaction().commit();
61:
62: assertNull(em.find(OWLClassA.class, entityA.getUri()));
63: verifyIndividualWasRemoved(entityA.getUri());
64: }
65:
66: // TODO First we need to resolve referential integrity
67: @Disabled
68: @Test
69: void testRemoveReference() {
70: this.em = getEntityManager("RemoveReference", false);
71: persist(entityD, entityA);
72:
73: final OWLClassA a = em.find(OWLClassA.class, entityA.getUri());
74: assertNotNull(a);
75: em.getTransaction().begin();
76: em.remove(a);
77: em.getTransaction().commit();
78:
79: assertNotNull(em.find(OWLClassD.class, entityD.getUri()));
80: assertNull(em.find(OWLClassA.class, entityA.getUri()));
81: }
82:
83: @Test
84: void testRemoveCascade() {
85: this.em = getEntityManager("RemoveCascade", false);
86: em.getTransaction().begin();
87: em.persist(entityG);
88: assertTrue(em.contains(entityG));
89: assertTrue(em.contains(entityH));
90: assertTrue(em.contains(entityA));
91: em.getTransaction().commit();
92:
93: em.getTransaction().begin();
94: final OWLClassG g = findRequired(OWLClassG.class, entityG.getUri());
95: final OWLClassH h = findRequired(OWLClassH.class, entityH.getUri());
96: final OWLClassA a = findRequired(OWLClassA.class, entityA.getUri());
97: assertTrue(em.contains(g));
98: assertTrue(em.contains(h));
99: assertTrue(em.contains(a));
100: assertNotNull(g);
101: em.remove(g);
102: assertFalse(em.contains(g));
103: assertFalse(em.contains(h));
104: assertFalse(em.contains(a));
105: em.getTransaction().commit();
106:
107: assertNull(em.find(OWLClassG.class, entityG.getUri()));
108: assertNull(em.find(OWLClassH.class, entityH.getUri()));
109: assertNull(em.find(OWLClassA.class, entityA.getUri()));
110: verifyIndividualWasRemoved(entityG.getUri());
111: verifyIndividualWasRemoved(entityH.getUri());
112: verifyIndividualWasRemoved(entityA.getUri());
113: }
114:
115: @Test
116: void testRemoveDetached() {
117: this.em = getEntityManager("RemoveDetached", false);
118: assertNull(entityE.getUri());
119: persist(entityE);
120: assertNotNull(entityE.getUri());
121:
122: em.getTransaction().begin();
123: final OWLClassE e = findRequired(OWLClassE.class, entityE.getUri());
124: assertTrue(em.contains(e));
125: em.detach(e);
126: assertFalse(em.contains(e));
127: assertThrows(IllegalArgumentException.class, () -> em.remove(e));
128: }
129:
130: @Test
131: void testRemoveNotYetCommitted() {
132: this.em = getEntityManager("RemoveNotYetCommitted", false);
133: em.getTransaction().begin();
134: em.persist(entityE);
135: assertTrue(em.contains(entityE));
136: em.remove(entityE);
137: assertFalse(em.contains(entityE));
138: em.getTransaction().commit();
139:
140: final OWLClassE res = em.find(OWLClassE.class, entityE.getUri());
141: assertNull(res);
142: }
143:
144: @Test
145: void testRemoveMergedWithCascading() {
146: this.em = getEntityManager("CascadeMergeAndRemove", false);
147: em.getTransaction().begin();
148: em.persist(entityG);
149: assertTrue(em.contains(entityA));
150: assertTrue(em.contains(entityG));
151: assertTrue(em.contains(entityH));
152: em.getTransaction().commit();
153: em.clear();
154:
155: final OWLClassG toDetach = findRequired(OWLClassG.class, entityG.getUri());
156: em.detach(toDetach);
157: assertFalse(em.contains(toDetach));
158: assertFalse(em.contains(toDetach.getOwlClassH()));
159: assertFalse(em.contains(toDetach.getOwlClassH().getOwlClassA()));
160:
161: em.getTransaction().begin();
162: final OWLClassG toRemove = em.merge(toDetach);
163: em.remove(toRemove);
164: em.getTransaction().commit();
165:
166: assertNull(em.find(OWLClassG.class, entityG.getUri()));
167: assertNull(em.find(OWLClassH.class, entityH.getUri()));
168: assertNull(em.find(OWLClassA.class, entityA.getUri()));
169: }
170:
171: @Test
172: void removeDeletesAllPropertyAssertionsMappedByEntity() {
173: this.em = getEntityManager("RemoveDeletesAllMappedAttributes", false);
174: entityC.setSimpleList(Generators.createSimpleList(5));
175: persistCWithLists(entityC);
176:
177: final OWLClassC toRemove = findRequired(OWLClassC.class, entityC.getUri());
178: em.getTransaction().begin();
179: em.remove(toRemove);
180: em.getTransaction().commit();
181:
182: final List<String> properties = resolveCProperties();
183: for (String prop : properties) {
184: assertFalse(
185: em.createNativeQuery("ASK WHERE { ?x ?p ?o .}", Boolean.class).setParameter("x", entityC.getUri())
186: .setParameter("p", URI.create(prop)).getSingleResult());
187: }
188: }
189:
190: private static List<String> resolveCProperties() {
191: final List<String> lst = new ArrayList<>();
192: for (Field f : OWLClassC.class.getDeclaredFields()) {
193: if (f.getAnnotation(Id.class) != null || EntityPropertiesUtils.isFieldTransient(f)) {
194: continue;
195: }
196: if (f.getAnnotation(OWLDataProperty.class) != null) {
197: lst.add(f.getAnnotation(OWLDataProperty.class).iri());
198: } else if (f.getAnnotation(OWLObjectProperty.class) != null) {
199: lst.add(f.getAnnotation(OWLObjectProperty.class).iri());
200: } else if (f.getAnnotation(OWLAnnotationProperty.class) != null) {
201: lst.add(f.getAnnotation(OWLAnnotationProperty.class).iri());
202: }
203: }
204: return lst;
205: }
206:
207: @Test
208: void testRemoveUnmappedPropertyValue() {
209: entityB.setProperties(Generators.createProperties());
210: this.em = getEntityManager("RemoveUnmappedPropertyValue", false);
211: em.getTransaction().begin();
212: em.persist(entityB);
213: em.getTransaction().commit();
214:
215: final String property = entityB.getProperties().keySet().iterator().next();
216: final Set<String> values = entityB.getProperties().get(property);
217: assertFalse(values.isEmpty());
218: final String valueToRemove = values.iterator().next();
219: em.getTransaction().begin();
220: final OWLClassB toUpdate = findRequired(OWLClassB.class, entityB.getUri());
221: assertNotNull(toUpdate.getProperties());
222: assertTrue(toUpdate.getProperties().containsKey(property));
223: assertTrue(toUpdate.getProperties().get(property).contains(valueToRemove));
224: toUpdate.getProperties().get(property).remove(valueToRemove);
225: em.getTransaction().commit();
226:
227: final OWLClassB result = findRequired(OWLClassB.class, entityB.getUri());
228: assertNotNull(result.getProperties());
229: assertTrue(result.getProperties().containsKey(property));
230: assertEquals(values.size() - 1, result.getProperties().get(property).size());
231: assertFalse(result.getProperties().get(property).contains(valueToRemove));
232: }
233:
234: @Test
235: void testRemoveAllValuesOfUnmappedProperty() {
236: entityB.setProperties(Generators.createProperties());
237: this.em = getEntityManager("RemoveAllValuesOfUnmappedProperty", false);
238: em.getTransaction().begin();
239: em.persist(entityB);
240: em.getTransaction().commit();
241:
242: final String property = entityB.getProperties().keySet().iterator().next();
243: em.getTransaction().begin();
244: final OWLClassB toUpdate = findRequired(OWLClassB.class, entityB.getUri());
245: assertNotNull(toUpdate.getProperties());
246: assertTrue(toUpdate.getProperties().containsKey(property));
247: toUpdate.getProperties().remove(property);
248: em.getTransaction().commit();
249:
250: final OWLClassB result = findRequired(OWLClassB.class, entityB.getUri());
251: assertNotNull(result.getProperties());
252: assertFalse(result.getProperties().containsKey(property));
253: }
254:
255: @Test
256: void testRemoveTypedUnmappedPropertyValue() {
257: this.em = getEntityManager("RemoveUnmappedPropertyValueTyped", false);
258: entityP.setProperties(Generators.createTypedProperties(10));
259: persist(entityP);
260:
261: em.getTransaction().begin();
262: final OWLClassP toUpdate = findRequired(OWLClassP.class, entityP.getUri());
263: for (Set<Object> set : toUpdate.getProperties().values()) {
264: final Iterator<Object> it = set.iterator();
265: while (it.hasNext()) {
266: it.next();
267: if (Generators.randomBoolean()) {
268: it.remove();
269: }
270: }
271: }
272: em.getTransaction().commit();
273: toUpdate.getProperties().keySet().removeIf(property -> toUpdate.getProperties().get(property).isEmpty());
274: if (toUpdate.getProperties().isEmpty()) {
275: toUpdate.setProperties(null);
276: }
277:
278: final OWLClassP res = findRequired(OWLClassP.class, entityP.getUri());
279: assertEquals(toUpdate.getProperties(), res.getProperties());
280: }
281:
282: @Test
283: void testRemoveAllValuesOfTypedUnmappedProperty() {
284: this.em = getEntityManager("RemoveAllValuesOfUnmappedPropertyTyped", false);
285: entityP.setProperties(Generators.createTypedProperties(15));
286: persist(entityP);
287:
288: final OWLClassP toUpdate = findRequired(OWLClassP.class, entityP.getUri());
289: em.detach(toUpdate);
290: // Copy the keys to prevent concurrent modification
291: final Set<URI> keys = new HashSet<>(toUpdate.getProperties().keySet());
292: keys.stream().filter(k -> Generators.randomBoolean())
293: .forEach(key -> toUpdate.getProperties().remove(key));
294: em.getTransaction().begin();
295: final OWLClassP merged = em.merge(toUpdate);
296: assertTrue(TestEnvironmentUtils.arePropertiesEqual(toUpdate.getProperties(), merged.getProperties()));
297: em.getTransaction().commit();
298:
299: final OWLClassP res = findRequired(OWLClassP.class, entityP.getUri());
300: assertTrue(TestEnvironmentUtils.arePropertiesEqual(toUpdate.getProperties(), res.getProperties()));
301: }
302:
303: @Test
304: void testRemoveAllValuesOfPluralPlainIdentifierObjectProperty() {
305: this.em = getEntityManager("RemoveAllValuesOfPluralPlainIdentifierOP", false);
306: entityP.setIndividuals(Generators.createUrls());
307: persist(entityP);
308:
309: final OWLClassP toUpdate = findRequired(OWLClassP.class, entityP.getUri());
310: em.getTransaction().begin();
311: toUpdate.getIndividuals().clear();
312: em.getTransaction().commit();
313:
314: final OWLClassP res = findRequired(OWLClassP.class, entityP.getUri());
315: assertThat(res.getIndividuals(), empty());
316: }
317:
318: @Test
319: void testSetAnnotationPropertyValueToNull() {
320: this.em = getEntityManager("SetAnnotationPropertyValueToNull", false);
321: entityN.setAnnotationProperty("annotationPropertyValue");
322: persist(entityN);
323:
324: final OWLClassN update = findRequired(OWLClassN.class, entityN.getId());
325: assertNotNull(update.getAnnotationProperty());
326: em.getTransaction().begin();
327: update.setAnnotationProperty(null);
328: em.getTransaction().commit();
329:
330: final OWLClassN res = findRequired(OWLClassN.class, entityN.getId());
331: assertNull(res.getAnnotationProperty());
332: }
333:
334: @Test
335: void testSetAnnotationPropertyValueContainingUriToNull() {
336: this.em = getEntityManager("SetAnnotationPropertyValueContainingUriToNull", false);
337: entityN.setAnnotationUri(URI.create("http://krizik.felk.cvut.cz/ontologies/jopa#annotationPropertyValue"));
338: persist(entityN);
339:
340: final OWLClassN update = findRequired(OWLClassN.class, entityN.getId());
341: assertNotNull(update.getAnnotationUri());
342: em.getTransaction().begin();
343: update.setAnnotationUri(null);
344: em.getTransaction().commit();
345:
346: final OWLClassN res = findRequired(OWLClassN.class, entityN.getId());
347: assertNull(res.getAnnotationUri());
348: }
349:
350: @Test
351: void testClearUriTypes() {
352: this.em = getEntityManager("ClearUriTypes", false);
353: entityP.setTypes(Generators.createUriTypes());
354: persist(entityP);
355:
356: em.getTransaction().begin();
357: final OWLClassP update = findRequired(OWLClassP.class, entityP.getUri());
358: update.getTypes().clear();
359: em.getTransaction().commit();
360:
361: final OWLClassP result = findRequired(OWLClassP.class, entityP.getUri());
362: assertTrue(result.getTypes().isEmpty());
363: }
364:
365: @Test
366: void testRemoveDetachedWithCascadedReferenceUsingMergeAndRemove() {
367: this.em = getEntityManager("RemoveDetachedEntityWithCascadedReferenceUsingMergeAndRemove", true);
368: persist(entityH);
369: assertNotNull(em.find(OWLClassH.class, entityH.getUri()));
370: assertNotNull(em.find(OWLClassA.class, entityA.getUri()));
371: final OWLClassH h = new OWLClassH();
372: h.setUri(entityH.getUri());
373: final OWLClassA a = new OWLClassA();
374: a.setUri(entityA.getUri());
375: a.setStringAttribute(entityA.getStringAttribute());
376: a.setTypes(new HashSet<>(entityA.getTypes()));
377: h.setOwlClassA(a);
378:
379: em.clear();
380: em.getTransaction().begin();
381: final OWLClassH toRemove = em.merge(h);
382: em.remove(toRemove);
383: em.getTransaction().commit();
384:
385: assertNull(em.find(OWLClassH.class, entityH.getUri()));
386: assertNull(em.find(OWLClassA.class, entityA.getUri()));
387: }
388:
389: @Test
390: void removeEntityTwiceInOneTransactionRemovesIt() {
391: this.em = getEntityManager("RemoveDetachedEntityWithCascadedReferenceUsingMergeAndRemove", true);
392: persist(entityA);
393:
394: em.getTransaction().begin();
395: final OWLClassA toRemove = em.merge(entityA);
396: em.remove(toRemove);
397: assertFalse(em.contains(toRemove));
398: em.remove(toRemove);
399: assertFalse(em.contains(toRemove));
400: em.getTransaction().commit();
401:
402: assertNull(em.find(OWLClassA.class, entityA.getUri()));
403: }
404:
405: @Test
406: public void settingDatatypeCollectionToNullRemovesAllValues() {
407: this.em = getEntityManager("settingDatatypeCollectionToNullRemovesAllValues", true);
408: persist(entityM);
409:
410: em.getTransaction().begin();
411: final OWLClassM toClear = findRequired(OWLClassM.class, entityM.getKey());
412: toClear.setIntegerSet(null);
413: em.getTransaction().commit();
414:
415: final OWLClassM result = findRequired(OWLClassM.class, entityM.getKey());
416: assertNull(result.getIntegerSet());
417: verifyDatatypePropertiesRemoved();
418: }
419:
420: private void verifyDatatypePropertiesRemoved() {
421: for (Integer value : entityM.getIntegerSet()) {
422: assertFalse(em.createNativeQuery("ASK { ?x ?p ?v . }", Boolean.class)
423: .setParameter("x", URI.create(entityM.getKey()))
424: .setParameter("p", URI.create(Vocabulary.p_m_IntegerSet)).setParameter("v", value)
425: .getSingleResult());
426: }
427: }
428:
429: @Test
430: public void clearingDatatypeCollectionRemovesAllValues() {
431: this.em = getEntityManager("clearingDatatypeCollectionRemovesAllValues", true);
432: persist(entityM);
433:
434: em.getTransaction().begin();
435: final OWLClassM toClear = findRequired(OWLClassM.class, entityM.getKey());
436: toClear.getIntegerSet().clear();
437: em.getTransaction().commit();
438:
439: final OWLClassM result = findRequired(OWLClassM.class, entityM.getKey());
440: // Could be the cached variant, which contains empty collection, or loaded from ontology, which contains null
441: assertTrue(result.getIntegerSet() == null || result.getIntegerSet().isEmpty());
442: verifyDatatypePropertiesRemoved();
443: }
444:
445: @Test
446: void removingNewlyPersistedInstanceRemovesPendingPersistsAndAllowsTransactionToFinish() {
447: this.em = getEntityManager("removingNewlyPersistedInstanceRemovesPendingPersistsAndAllowsTransactionToFinish",
448: true);
449: em.getTransaction().begin();
450: em.persist(entityD);
451: em.remove(entityD);
452: em.getTransaction().commit();
453:
454: assertNull(em.find(OWLClassD.class, entityD.getUri()));
455: assertNull(em.find(OWLClassA.class, entityA.getUri()));
456: }
457:
458: @Test
459: void removeClearsPluralAnnotationPropertyValues() {
460: this.em = getEntityManager("removeClearsPluralAnnotationPropertyValues", false);
461: final Set<String> annotations = IntStream.range(0, 5).mapToObj(i -> "Source" + i).collect(Collectors.toSet());
462: entityN.setPluralAnnotationProperty(annotations);
463: persist(entityN);
464:
465: em.getTransaction().begin();
466: final OWLClassN toRemove = findRequired(OWLClassN.class, entityN.getId());
467: em.remove(toRemove);
468: em.getTransaction().commit();
469:
470: assertTrue(em.createNativeQuery("SELECT * WHERE { ?x ?hasSource ?source . }")
471: .setParameter("hasSource", URI.create(DC.Terms.SOURCE)).getResultList().isEmpty());
472: }
473:
474: @Test
475: void removeWorksForInstanceRetrievedUsingGetReference() {
476: this.em = getEntityManager("removeWorksForInstanceRetrievedUsingGetReference", false);
477: persist(entityM);
478: em.getTransaction().begin();
479: final OWLClassM toRemove = em.getReference(OWLClassM.class, entityM.getKey());
480: em.remove(toRemove);
481: em.getTransaction().commit();
482:
483: assertNull(em.find(OWLClassM.class, entityM.getKey()));
484: assertFalse(
485: em.createNativeQuery("ASK { ?x ?y ?z .}", Boolean.class).setParameter("x", URI.create(entityM.getKey()))
486: .getSingleResult());
487: }
488:
489: @Test
490: void removeDeletesSimpleLiteralStatement() {
491: this.em = getEntityManager("removeDeletesSimpleLiteralStatement", true);
492: entityM.setSimpleLiteral("simple literal value");
493: persist(entityM);
494:
495: em.getTransaction().begin();
496: em.remove(findRequired(OWLClassM.class, entityM.getKey()));
497: em.getTransaction().commit();
498:
499: assertFalse(
500: em.createNativeQuery("ASK { ?x ?y ?z .}", Boolean.class).setParameter("x", URI.create(entityM.getKey()))
501: .getSingleResult());
502: }
503: }