/*****************************************************************
* 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;
import java.util.List;
import org.apache.cayenne.access.ToManyList;
import org.apache.cayenne.configuration.server.ServerRuntime;
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.test.jdbc.DBHelper;
import org.apache.cayenne.test.jdbc.TableHelper;
import org.apache.cayenne.testdo.testmap.ArtGroup;
import org.apache.cayenne.testdo.testmap.Artist;
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.ServerCase;
import org.apache.cayenne.unit.di.server.UseServerRuntime;
@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
public class CayenneDataObjectRelationshipsTest extends ServerCase {
@Inject
private ObjectContext context;
@Inject
private ServerRuntime runtime;
@Inject
private DBHelper dbHelper;
private TableHelper tArtist;
private TableHelper tPaintingInfo;
private TableHelper tPainting;
@Override
protected void setUpAfterInjection() throws Exception {
dbHelper.deleteAll("PAINTING_INFO");
dbHelper.deleteAll("PAINTING");
dbHelper.deleteAll("ARTIST_EXHIBIT");
dbHelper.deleteAll("ARTIST_GROUP");
dbHelper.deleteAll("ARTIST");
tArtist = new TableHelper(dbHelper, "ARTIST");
tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
tPainting = new TableHelper(dbHelper, "PAINTING");
tPainting.setColumns(
"PAINTING_ID",
"PAINTING_TITLE",
"ARTIST_ID");
tPaintingInfo = new TableHelper(dbHelper, "PAINTING_INFO");
tPaintingInfo.setColumns("PAINTING_ID", "TEXT_REVIEW");
}
private void createArtistWithPaintingDataSet() throws Exception {
tArtist.insert(8, "aX");
tPainting.insert(6, "pW", 8);
}
private void createArtistWithPaintingAndInfoDataSet() throws Exception {
tArtist.insert(8, "aX");
tPainting.insert(6, "pW", 8);
tPaintingInfo.insert(6, "mE");
}
public void testReadNestedProperty1() throws Exception {
createArtistWithPaintingDataSet();
Painting p1 = Cayenne.objectForPK(context, Painting.class, 6);
assertEquals("aX", p1.readNestedProperty("toArtist.artistName"));
}
public void testReadNestedProperty2() throws Exception {
createArtistWithPaintingDataSet();
Painting p1 = Cayenne.objectForPK(context, Painting.class, 6);
assertTrue(p1.getToArtist().readNestedProperty("paintingArray") instanceof List<?>);
}
public void testReciprocalRel1() throws Exception {
createArtistWithPaintingDataSet();
Painting p1 = Cayenne.objectForPK(context, Painting.class, 6);
Artist a1 = p1.getToArtist();
assertNotNull(a1);
assertEquals("aX", a1.getArtistName());
List<Painting> paintings = a1.getPaintingArray();
assertEquals(1, paintings.size());
Painting p2 = paintings.get(0);
assertSame(p1, p2);
}
public void testReadToOneRel1() throws Exception {
createArtistWithPaintingDataSet();
Painting p1 = Cayenne.objectForPK(context, Painting.class, 6);
Artist a1 = p1.getToArtist();
assertNotNull(a1);
assertEquals(PersistenceState.HOLLOW, a1.getPersistenceState());
assertEquals("aX", a1.getArtistName());
assertEquals(PersistenceState.COMMITTED, a1.getPersistenceState());
}
public void testReadToOneRel2() throws Exception {
// test chained calls to read relationships
createArtistWithPaintingAndInfoDataSet();
PaintingInfo pi1 = Cayenne.objectForPK(context, PaintingInfo.class, 6);
Painting p1 = pi1.getPainting();
p1.getPaintingTitle();
Artist a1 = p1.getToArtist();
assertNotNull(a1);
assertEquals(PersistenceState.HOLLOW, a1.getPersistenceState());
assertEquals("aX", a1.getArtistName());
assertEquals(PersistenceState.COMMITTED, a1.getPersistenceState());
}
public void testReadToOneRel3() throws Exception {
createArtistWithPaintingDataSet();
Painting p1 = Cayenne.objectForPK(context, Painting.class, 6);
Gallery g1 = p1.getToGallery();
assertNull(g1);
}
public void testReadToManyRel1() throws Exception {
createArtistWithPaintingDataSet();
Artist a1 = Cayenne.objectForPK(context, Artist.class, 8);
List<Painting> plist = a1.getPaintingArray();
assertNotNull(plist);
assertEquals(1, plist.size());
assertEquals(PersistenceState.COMMITTED, plist.get(0).getPersistenceState());
assertEquals("pW", plist.get(0).getPaintingTitle());
}
public void testReadToManyRel2() throws Exception {
// test empty relationship
tArtist.insert(11, "aX");
Artist a1 = Cayenne.objectForPK(context, Artist.class, 11);
List<Painting> plist = a1.getPaintingArray();
assertNotNull(plist);
assertEquals(0, plist.size());
}
public void testReflexiveRelationshipInsertOrder1() {
ArtGroup parentGroup = context.newObject(ArtGroup.class);
parentGroup.setName("parent");
ArtGroup childGroup1 = context.newObject(ArtGroup.class);
childGroup1.setName("child1");
childGroup1.setToParentGroup(parentGroup);
context.commitChanges();
}
public void testReflexiveRelationshipInsertOrder2() {
ArtGroup childGroup1 = context.newObject(ArtGroup.class);
childGroup1.setName("child1");
ArtGroup parentGroup = context.newObject(ArtGroup.class);
parentGroup.setName("parent");
childGroup1.setToParentGroup(parentGroup);
context.commitChanges();
}
public void testReflexiveRelationshipInsertOrder3() {
// multiple children, one created before parent, one after
ArtGroup childGroup1 = context.newObject(ArtGroup.class);
childGroup1.setName("child1");
ArtGroup parentGroup = context.newObject(ArtGroup.class);
parentGroup.setName("parent");
childGroup1.setToParentGroup(parentGroup);
ArtGroup childGroup2 = context.newObject(ArtGroup.class);
childGroup2.setName("child2");
childGroup2.setToParentGroup(parentGroup);
context.commitChanges();
}
public void testReflexiveRelationshipInsertOrder4() {
// multiple children, one created before parent, one after
ArtGroup childGroup1 = context.newObject(ArtGroup.class);
childGroup1.setName("child1");
ArtGroup parentGroup = context.newObject(ArtGroup.class);
parentGroup.setName("parent");
childGroup1.setToParentGroup(parentGroup);
ArtGroup childGroup2 = context.newObject(ArtGroup.class);
childGroup2.setName("subchild");
childGroup2.setToParentGroup(childGroup1);
context.commitChanges();
}
public void testCrossContextRelationshipException() {
// Create this object in one context...
Artist artist = context.newObject(Artist.class);
// ...and this object in another context
Painting painting = runtime.newContext().newObject(Painting.class);
// Check setting a toOne relationship
try {
painting.setToArtist(artist);
fail("Should have failed to set a cross-context relationship");
}
catch (CayenneRuntimeException e) {
// Fine.. it should throw an exception
}
assertNull(painting.getToArtist()); // Make sure it wasn't set
// Now try the reverse (toMany) relationship
try {
artist.addToPaintingArray(painting);
fail("Should have failed to add a cross-context relationship");
}
catch (CayenneRuntimeException e) {
// Fine.. it should throw an exception
}
assertEquals(0, artist.getPaintingArray().size());
}
public void testComplexInsertUpdateOrdering() {
Artist artist = context.newObject(Artist.class);
artist.setArtistName("a name");
context.commitChanges();
// Cause an update and an insert that need correct ordering
Painting painting = context.newObject(Painting.class);
painting.setPaintingTitle("a painting");
artist.addToPaintingArray(painting);
context.commitChanges();
context.deleteObjects(artist);
context.commitChanges();
}
public void testNewToMany() throws Exception {
Artist artist = context.newObject(Artist.class);
artist.setArtistName("test");
assertTrue(artist.readPropertyDirectly("paintingArray") instanceof ToManyList);
ToManyList list = (ToManyList) artist.readPropertyDirectly("paintingArray");
assertFalse(list.isFault());
context.commitChanges();
assertFalse(list.isFault());
}
}