/***************************************************************** * 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 org.apache.cayenne.DataObject; import org.apache.cayenne.ObjectContext; import org.apache.cayenne.PersistenceState; import org.apache.cayenne.ValueHolder; import org.apache.cayenne.di.Inject; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.cayenne.query.SelectQuery; import org.apache.cayenne.test.jdbc.DBHelper; import org.apache.cayenne.test.jdbc.TableHelper; import org.apache.cayenne.testdo.testmap.Artist; import org.apache.cayenne.testdo.testmap.Painting; import org.apache.cayenne.unit.di.DataChannelInterceptor; import org.apache.cayenne.unit.di.UnitTestClosure; 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.Before; import org.junit.Test; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @UseServerRuntime(CayenneProjects.TESTMAP_PROJECT) public class SimpleIdIncrementalFaultListPrefetchIT extends ServerCase { @Inject protected ObjectContext context; @Inject protected DBHelper dbHelper; @Inject protected DataChannelInterceptor queryInterceptor; protected TableHelper tArtist; protected TableHelper tPaining; @Before public void setUp() throws Exception { tArtist = new TableHelper(dbHelper, "ARTIST"); tArtist.setColumns("ARTIST_ID", "ARTIST_NAME"); tPaining = new TableHelper(dbHelper, "PAINTING"); tPaining.setColumns( "PAINTING_ID", "PAINTING_TITLE", "ARTIST_ID", "ESTIMATED_PRICE"); } protected void createArtistsDataSet() throws Exception { tArtist.insert(33001, "artist11"); tArtist.insert(33002, "artist12"); tArtist.insert(33003, "artist13"); tArtist.insert(33004, "artist14"); tArtist.insert(33005, "artist15"); tArtist.insert(33006, "artist16"); tArtist.insert(33007, "artist21"); } protected void createArtistsAndPaintingsDataSet() throws Exception { createArtistsDataSet(); tPaining.insert(33001, "P_artist11", 33001, 1000); tPaining.insert(33002, "P_artist12", 33002, 2000); tPaining.insert(33003, "P_artist13", 33003, 3000); tPaining.insert(33004, "P_artist14", 33004, 4000); tPaining.insert(33005, "P_artist15", 33005, 5000); tPaining.insert(33006, "P_artist16", 33006, 11000); tPaining.insert(33007, "P_artist21", 33007, 21000); } @Test public void testListType() throws Exception { createArtistsDataSet(); Expression e = Artist.ARTIST_NAME.like("artist1%"); SelectQuery q = new SelectQuery("Artist", e); q.setPageSize(4); List<?> result = context.performQuery(q); assertTrue(result instanceof SimpleIdIncrementalFaultList); } /** * Test that all queries specified in prefetch are executed with a single prefetch * path. */ @Test public void testPrefetch1() throws Exception { createArtistsAndPaintingsDataSet(); Expression e = ExpressionFactory.likeExp("artistName", "artist1%"); SelectQuery q = new SelectQuery("Artist", e); q.addPrefetch("paintingArray"); q.setPageSize(3); final IncrementalFaultList<?> result = (IncrementalFaultList) context .performQuery(q); assertEquals(6, result.size()); // currently queries with prefetch do not resolve their first page assertEquals(result.size(), result.getUnfetchedObjects()); int count = queryInterceptor.runWithQueryCounter(new UnitTestClosure() { public void execute() { // go through the second page objects and count queries for (int i = 3; i < 6; i++) { result.get(i); } } }); // within the same page only one query should've been executed assertEquals(1, count); } /** * Test that a to-many relationship is initialized. */ @Test public void testPrefetch3() throws Exception { createArtistsAndPaintingsDataSet(); Expression e = ExpressionFactory.likeExp("artistName", "artist1%"); SelectQuery q = new SelectQuery("Artist", e); q.addPrefetch("paintingArray"); q.setPageSize(3); IncrementalFaultList result = (IncrementalFaultList) context.performQuery(q); assertEquals(6, result.size()); // currently queries with prefetch do not resolve their first page assertEquals(result.size(), result.getUnfetchedObjects()); // go through the second page objects and check their to many for (int i = 3; i < 6; i++) { Artist a = (Artist) result.get(i); List paintings = a.getPaintingArray(); assertFalse(((ValueHolder) paintings).isFault()); assertEquals(1, paintings.size()); } } /** * Test that a to-one relationship is initialized. */ @Test public void testPrefetch4() throws Exception { createArtistsAndPaintingsDataSet(); SelectQuery q = new SelectQuery(Painting.class); q.setPageSize(3); q.addPrefetch("toArtist"); IncrementalFaultList<?> result = (IncrementalFaultList) context.performQuery(q); // get an objects from the second page final DataObject p1 = (DataObject) result.get(q.getPageSize()); queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() { public void execute() { Object toOnePrefetch = p1.readNestedProperty("toArtist"); assertNotNull(toOnePrefetch); assertTrue( "Expected DataObject, got: " + toOnePrefetch.getClass().getName(), toOnePrefetch instanceof DataObject); DataObject a1 = (DataObject) toOnePrefetch; assertEquals(PersistenceState.COMMITTED, a1.getPersistenceState()); } }); } }