/***************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. ****************************************************************/ package org.apache.cayenne.access; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.sql.Types; import java.util.List; import org.apache.cayenne.PersistenceState; import org.apache.cayenne.di.Inject; import org.apache.cayenne.query.SQLTemplate; import org.apache.cayenne.test.jdbc.DBHelper; import org.apache.cayenne.testdo.testmap.ArtGroup; import org.apache.cayenne.testdo.testmap.Artist; import org.apache.cayenne.testdo.testmap.ArtistExhibit; import org.apache.cayenne.testdo.testmap.Exhibit; import org.apache.cayenne.testdo.testmap.Gallery; import org.apache.cayenne.testdo.testmap.Painting; import org.apache.cayenne.testdo.testmap.PaintingInfo; import org.apache.cayenne.unit.di.server.CayenneProjects; import org.apache.cayenne.unit.di.server.ServerCase; import org.apache.cayenne.unit.di.server.UseServerRuntime; import org.junit.Test; // TODO: redefine all test cases in terms of entities in "relationships" map // and merge this test case with DeleteRulesTst that inherits // from RelationshipTestCase. @UseServerRuntime(CayenneProjects.TESTMAP_PROJECT) public class DataContextDeleteRulesIT extends ServerCase { @Inject private DataContext context; @Inject private DBHelper dbHelper; @Override public void cleanUpDB() throws Exception { dbHelper.update("ARTGROUP").set("PARENT_GROUP_ID", null, Types.INTEGER).execute(); super.cleanUpDB(); } @Test public void testNullifyToOne() { // ArtGroup toParentGroup ArtGroup parentGroup = (ArtGroup) context.newObject("ArtGroup"); parentGroup.setName("Parent"); ArtGroup childGroup = (ArtGroup) context.newObject("ArtGroup"); childGroup.setName("Child"); parentGroup.addToChildGroupsArray(childGroup); // Check to make sure that the relationships are both exactly correct // before starting. We're not really testing this, but it is imperative // that it is correct before testing the real details. assertEquals(parentGroup, childGroup.getToParentGroup()); assertTrue(parentGroup.getChildGroupsArray().contains(childGroup)); // Always good to commit before deleting... bad things happen otherwise context.commitChanges(); context.deleteObjects(childGroup); // The things we are testing. assertFalse(parentGroup.getChildGroupsArray().contains(childGroup)); // Although deleted, the property should be null (good cleanup policy) // assertNull(childGroup.getToParentGroup()); // And be sure that the commit works afterwards, just for sanity context.commitChanges(); } /** * Tests that deleting a source of a flattened relationship with CASCADE * rule results in deleting a join and a target. */ @Test public void testCascadeToManyFlattened() { // testing Artist.groupArray relationship ArtGroup aGroup = context.newObject(ArtGroup.class); aGroup.setName("Group Name"); Artist anArtist = context.newObject(Artist.class); anArtist.setArtistName("A Name"); anArtist.addToGroupArray(aGroup); assertTrue(anArtist.getGroupArray().contains(aGroup)); context.commitChanges(); SQLTemplate checkQuery = new SQLTemplate(Artist.class, "SELECT * FROM ARTIST_GROUP"); checkQuery.setFetchingDataRows(true); List<?> joins1 = context.performQuery(checkQuery); assertEquals(1, joins1.size()); context.deleteObjects(anArtist); assertEquals(PersistenceState.DELETED, aGroup.getPersistenceState()); assertFalse(anArtist.getGroupArray().contains(aGroup)); context.commitChanges(); List<?> joins2 = context.performQuery(checkQuery); assertEquals(0, joins2.size()); } /** * Tests that deleting a source of a flattened relationship with NULLIFY * rule results in deleting a join together with the object deleted. */ @Test public void testNullifyToManyFlattened() { // testing ArtGroup.artistArray relationship ArtGroup aGroup = context.newObject(ArtGroup.class); aGroup.setName("Group Name"); Artist anArtist = context.newObject(Artist.class); anArtist.setArtistName("A Name"); aGroup.addToArtistArray(anArtist); context.commitChanges(); // Preconditions assertTrue(aGroup.getArtistArray().contains(anArtist)); assertTrue(anArtist.getGroupArray().contains(aGroup)); SQLTemplate checkQuery = new SQLTemplate(Artist.class, "SELECT * FROM ARTIST_GROUP"); checkQuery.setFetchingDataRows(true); List<?> joins1 = context.performQuery(checkQuery); assertEquals(1, joins1.size()); context.deleteObjects(aGroup); assertFalse(anArtist.getGroupArray().contains(aGroup)); context.commitChanges(); List<?> joins2 = context.performQuery(checkQuery); assertEquals(0, joins2.size()); } @Test public void testNullifyToMany() { // ArtGroup childGroupsArray ArtGroup parentGroup = (ArtGroup) context.newObject("ArtGroup"); parentGroup.setName("Parent"); ArtGroup childGroup = (ArtGroup) context.newObject("ArtGroup"); childGroup.setName("Child"); parentGroup.addToChildGroupsArray(childGroup); // Preconditions - good to check to be sure assertEquals(parentGroup, childGroup.getToParentGroup()); assertTrue(parentGroup.getChildGroupsArray().contains(childGroup)); context.commitChanges(); context.deleteObjects(parentGroup); // The things we are testing. assertNull(childGroup.getToParentGroup()); // Although deleted, the property should be null (good cleanup policy) // assertFalse(parentGroup.getChildGroupsArray().contains(childGroup)); context.commitChanges(); } @Test public void testCascadeToOne() { // Painting toPaintingInfo Painting painting = (Painting) context.newObject("Painting"); painting.setPaintingTitle("A Title"); PaintingInfo info = (PaintingInfo) context.newObject("PaintingInfo"); painting.setToPaintingInfo(info); // Must commit before deleting.. this relationship is dependent, // and everything must be committed for certain things to work context.commitChanges(); context.deleteObjects(painting); // info must also be deleted assertEquals(PersistenceState.DELETED, info.getPersistenceState()); assertNull(info.getPainting()); assertNull(painting.getToPaintingInfo()); context.commitChanges(); } @Test public void testCascadeToMany() { // Artist artistExhibitArray Artist anArtist = (Artist) context.newObject("Artist"); anArtist.setArtistName("A Name"); Exhibit anExhibit = (Exhibit) context.newObject("Exhibit"); anExhibit.setClosingDate(new java.sql.Timestamp(System.currentTimeMillis())); anExhibit.setOpeningDate(new java.sql.Timestamp(System.currentTimeMillis())); // Needs a gallery... required for data integrity Gallery gallery = (Gallery) context.newObject("Gallery"); gallery.setGalleryName("A Name"); anExhibit.setToGallery(gallery); ArtistExhibit artistExhibit = (ArtistExhibit) context.newObject("ArtistExhibit"); artistExhibit.setToArtist(anArtist); artistExhibit.setToExhibit(anExhibit); context.commitChanges(); context.deleteObjects(anArtist); // Test that the link record was deleted, and removed from the // relationship assertEquals(PersistenceState.DELETED, artistExhibit.getPersistenceState()); assertFalse(anArtist.getArtistExhibitArray().contains(artistExhibit)); context.commitChanges(); } @Test public void testDenyToMany() { // Gallery paintingArray Gallery gallery = (Gallery) context.newObject("Gallery"); gallery.setGalleryName("A Name"); Painting painting = (Painting) context.newObject("Painting"); painting.setPaintingTitle("A Title"); gallery.addToPaintingArray(painting); context.commitChanges(); try { context.deleteObjects(gallery); fail("Should have thrown an exception"); } catch (Exception e) { // GOOD! } context.commitChanges(); } }