db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject svn commit: r513565 - in /db/ojb/branches/OJB_1_0_RELEASE/src: schema/ test/org/apache/ojb/ test/org/apache/ojb/broker/ test/org/apache/ojb/broker/sequence/
Date Fri, 02 Mar 2007 00:52:49 GMT
Author: arminw
Date: Thu Mar  1 16:52:47 2007
New Revision: 513565

URL: http://svn.apache.org/viewvc?view=rev&rev=513565
Log:
add tests, update to check 
- new database dependent LIMIT/OFFSET support
- support of Statement.getGeneratedKeys() in database identity column based SequenceManager

Added:
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PaginationTest.java
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_pagination.xml
Modified:
    db/ojb/branches/OJB_1_0_RELEASE/src/schema/ojbtest-schema.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/AllTests.java
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PersistenceBrokerTest.java
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityHsqlTest.java
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMaxDBTest.java
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMySqlTest.java
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityTest.java
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_database.xml
    db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_meta_seq.xml

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/schema/ojbtest-schema.xml
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/schema/ojbtest-schema.xml?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/schema/ojbtest-schema.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/schema/ojbtest-schema.xml Thu Mar  1 16:52:47 2007
@@ -1937,4 +1937,114 @@
 		</foreign-key>
 	</table>
 
+
+    <table name="PAGE_BOOK">
+        <column
+           name="ID_"
+           type="INTEGER"
+           primaryKey="true"
+           autoIncrement="true"/>
+        <column
+           name="TITLE_"
+           type="VARCHAR"/>
+        <column
+           name="DATE_"
+           type="TIMESTAMP"/>
+        <column
+           name="COVER_"
+           type="LONGVARBINARY"/>
+        <column
+           name="VERSION_"
+           type="INTEGER"/>
+        <column
+           name="FK_PUBLISHER"
+           type="INTEGER"/>
+        <foreign-key foreignTable="PAGE_PUBLISHER">
+                <reference local="FK_PUBLISHER" foreign="ID_"/>
+        </foreign-key>
+    </table>
+
+    <table name="PAGE_PUBLICATION">
+        <column
+           name="BOOK_ID"
+           type="INTEGER"
+           primaryKey="true"
+           required="true"/>
+        <column
+           name="AUTHOR_ID"
+           type="INTEGER"
+           primaryKey="true"
+           required="true"/>
+        <foreign-key foreignTable="PAGE_BOOK">
+                <reference local="BOOK_ID" foreign="ID_"/>
+        </foreign-key>
+        <foreign-key foreignTable="PAGE_AUTHOR">
+                <reference local="AUTHOR_ID" foreign="ID_"/>
+        </foreign-key>
+    </table>
+
+    <table name="PAGE_PUBLISHER">
+        <column
+           name="ID_"
+           type="INTEGER"
+           primaryKey="true"
+           autoIncrement="true"/>
+        <column
+           name="NAME_"
+           type="VARCHAR"/>
+        <column
+           name="VERSION_"
+           type="INTEGER"/>
+    </table>
+
+    <table name="PAGE_AUTHOR">
+        <column
+           name="ID_"
+           type="INTEGER"
+           primaryKey="true"
+           autoIncrement="true"/>
+        <column
+           name="NAME_"
+           type="VARCHAR"/>
+        <column
+           name="VERSION_"
+           type="INTEGER"/>
+        <column
+           name="FK_PUBLISHER"
+           type="INTEGER"/>
+        <foreign-key foreignTable="PAGE_PUBLISHER">
+                <reference local="FK_PUBLISHER" foreign="ID_"/>
+        </foreign-key>
+    </table>
+
+    <table name="PAGE_REVIEW">
+        <column
+           name="ID_"
+           type="INTEGER"
+           primaryKey="true"
+           autoIncrement="true"/>
+        <column
+           name="VOTE_"
+           type="INTEGER"/>
+        <column
+           name="SUMMARY_"
+           type="VARCHAR"/>
+        <column
+           name="VERSION_"
+           type="INTEGER"/>
+        <column
+           name="FK_AUTHOR"
+           type="INTEGER"/>
+        <column
+           name="FK_BOOK"
+           type="INTEGER"/>
+        <foreign-key foreignTable="PAGE_AUTHOR">
+                <reference local="FK_AUTHOR" foreign="ID_"/>
+        </foreign-key>
+        <foreign-key foreignTable="PAGE_BOOK">
+                <reference local="FK_BOOK" foreign="ID_"/>
+        </foreign-key>
+    </table>
+
+
 </database>

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/AllTests.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/AllTests.java?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/AllTests.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/AllTests.java Thu Mar  1 16:52:47 2007
@@ -127,6 +127,7 @@
         suite.addTestSuite(OptimisticLockingMultithreadedTest.class);
         suite.addTestSuite(NoPkReferenceTest.class);
         suite.addTestSuite(UnwrapHelperTest.class);
+        suite.addTestSuite(PaginationTest.class);
         suite.addTestSuite(LOBTest.class);
         suite.addTestSuite(JdbcJavaObjectTest.class);
         suite.addTestSuite(StoredProcedureMaxDBTest.class);

Added: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PaginationTest.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PaginationTest.java?view=auto&rev=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PaginationTest.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PaginationTest.java Thu Mar  1 16:52:47 2007
@@ -0,0 +1,1351 @@
+package org.apache.ojb.broker;
+
+/* Copyright 2002-2007 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+import java.lang.Object;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.ojb.junit.PBTestCase;
+import org.apache.ojb.broker.query.Query;
+import org.apache.ojb.broker.query.QueryFactory;
+import org.apache.ojb.broker.query.Criteria;
+import org.apache.ojb.broker.query.QueryByCriteria;
+import org.apache.ojb.broker.util.ObjectModification;
+import org.apache.ojb.broker.accesslayer.OJBIterator;
+import org.apache.ojb.broker.accesslayer.RsIterator;
+import org.apache.ojb.broker.accesslayer.ChainingIterator;
+import org.apache.ojb.broker.accesslayer.PagingIterator;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.commons.lang.ClassUtils;
+
+/**
+ * Test OJB's pagination and limit concepts.
+ */
+public class PaginationTest extends PBTestCase
+{
+    public static void main(String[] args)
+    {
+        String[] arr = {PaginationTest.class.getName()};
+        junit.textui.TestRunner.main(arr);
+    }
+
+    public PaginationTest(String name)
+    {
+        super(name);
+    }
+
+    public void setUp() throws Exception
+    {
+        super.setUp();
+    }
+
+    public void tearDown() throws Exception
+    {
+        super.tearDown();
+    }
+
+    private void insertTestData(String appendix)
+    {
+        Book b1 = new Book("book_1" + appendix, new Date(1), null);
+        Author a1 = new Author("author_1" + appendix, null);
+        Author a2 = new Author("author_2" + appendix, null);
+        Author a3 = new Author("author_3" + appendix, null);
+        Author a4 = new Author("author_4" + appendix, null);
+        Review r = new Review("review" + appendix, new Integer(30));
+        Publisher p = new PublisherImpl("publisher" + appendix);
+
+        p.addAuthor(a1);
+        p.addAuthor(a2);
+        p.addAuthor(a3);
+        p.addAuthor(a4);
+        a1.setPublisher(p);
+        a2.setPublisher(p);
+        a3.setPublisher(p);
+        a4.setPublisher(p);
+
+        List reviews = new ArrayList();
+        for(int i=0; i<10; i++)
+        {
+            Review rev = new Review("review_" + i  + appendix, new Integer(10 * i));
+            rev.setAuthor(new Author("review_author" + i + appendix, null));
+            rev.setBook(b1);
+            reviews.add(rev);
+        }
+        b1.setReviews(reviews);
+        a1.addBook(b1);
+        b1.addAuthor(a1);
+        b1.setPublisher(p);
+
+        broker.beginTransaction();
+        // it's a circular object graph, so insert the plain start object first
+        // and then update it with all references
+        broker.store(b1, ObjectModification.INSERT, true);
+        broker.serviceConnectionManager().executeBatch();
+        broker.store(b1);
+        broker.commitTransaction();
+
+    }
+
+    private void deleteTestData(String appendix)
+    {
+        broker.serviceConnectionManager().setBatchMode(false);
+        broker.beginTransaction();
+        Query q = QueryFactory.newQuery(Book.class, new Criteria().addLike("title", "%"+appendix));
+        List books = new ArrayList(broker.getCollectionByQuery(q));
+        for(int i = 0; i < books.size(); i++)
+        {
+            Object o =  books.get(i);
+            broker.delete(o);
+        }
+        broker.commitTransaction();
+    }
+
+    public void testLimit_1()
+    {
+        String appendix = "_testLimit_1_" + System.currentTimeMillis();
+        performLimit(appendix, 1, 1, 10);
+    }
+
+    public void testLimit_3()
+    {
+        String appendix = "_testLimit_3_" + System.currentTimeMillis();
+        performLimit(appendix, 3, 3, 30);
+    }
+
+    public void testLimit_2()
+    {
+        String appendix = "_testLimit_2_" + System.currentTimeMillis();
+        performLimit(appendix, 9, 9, 90);
+    }
+
+    public void testLimit_4()
+    {
+        String appendix = "_testLimit_4_" + System.currentTimeMillis();
+        performLimit(appendix, 10, 9, 90);
+    }
+
+    public void performLimit(String appendix, int limit, int expectedSize, int voteLessOrEqual)
+    {
+        insertTestData(appendix);
+
+        // first check query without limit, this returns all Review objects with
+        // 'vote' >= 10 ===> expect 9 objects
+        Criteria crit = new Criteria()
+                        .addGreaterOrEqualThan("vote", new Integer(10))
+                        .addLike("book.title", "%"+appendix);
+        QueryByCriteria query = QueryFactory.newQuery(Review.class, crit);
+        // NOTE: If pagination/limit is used it's strongly recommended to order by
+        // a unique column to avoid problems with different result order
+        // ('vote' isn't unique, thus add PK field)
+        query.addOrderByAscending("vote");
+        query.addOrderByAscending("id");
+        // NOTE: if we use pagination it's mandatory not to query "extents" too,
+        // because else it will end in multiple limit queries (one for each extent)
+        // thus the result will be pagination_size * extents
+        query.setWithExtents(false);
+
+        // check result without limit
+        Collection result = broker.getCollectionByQuery(query);
+        assertEquals(9, result.size());
+        for(Iterator iterator = result.iterator(); iterator.hasNext();)
+        {
+            Review r =  (Review) iterator.next();
+            assertTrue(r.getVote().intValue() >= 10);
+            assertNotNull(r.getBook());
+            assertTrue(r.getBook().getTitle().endsWith(appendix));
+        }
+
+        // now start the real work: perform LIMIT query
+        query = QueryFactory.newQuery(Review.class, crit);
+        // NOTE: If pagination/limit is used it's strongly recommended to order by
+        // a unique column to avoid problems with different result order
+        // ('vote' isn't unique, thus add PK field)
+        query.addOrderByAscending("vote");
+        query.addOrderByAscending("id");
+        // NOTE: if we use pagination it's mandatory not to query "extents" too,
+        // because else it will end in multiple limit queries (one for each extent)
+        // thus the result will be pagination_size * extents
+        query.setWithExtents(false);
+        // query with limit
+        query.setEndAtIndex(limit);
+        result = broker.getCollectionByQuery(query);
+
+        assertEquals(expectedSize, result.size());
+        for(Iterator iterator = result.iterator(); iterator.hasNext();)
+        {
+            Review r =  (Review) iterator.next();
+            assertTrue(r.getVote().intValue() >= 10);
+            assertTrue(r.getVote().intValue() <= voteLessOrEqual);
+            assertNotNull(r.getBook());
+            assertTrue(r.getBook().getTitle().endsWith(appendix));
+        }
+
+        deleteTestData(appendix);
+    }
+
+    public void testLimitOffset_1()
+    {
+        String appendix = "_testLimitOffset_1_" + System.currentTimeMillis();
+        int start = 1;
+        int end = 1;
+        int expectedSize = 1;
+        int voteGreaterEquals = 10;
+        int voteLessEquals = 10;
+        performLimitOffest(appendix, start, end, expectedSize, voteGreaterEquals, voteLessEquals);
+    }
+
+    public void testLimitOffset_2()
+    {
+        String appendix = "_testLimitOffset_2_" + System.currentTimeMillis();
+        int start = 4;
+        int end = 4;
+        int expectedSize = 1;
+        int voteGreaterEquals = 40;
+        int voteLessEquals = 40;
+        performLimitOffest(appendix, start, end, expectedSize, voteGreaterEquals, voteLessEquals);
+    }
+
+    public void testLimitOffset_3()
+    {
+        String appendix = "_testLimitOffset_3_" + System.currentTimeMillis();
+        int start = 1;
+        int end = 8;
+        int expectedSize = 8;
+        int voteGreaterEquals = 10;
+        int voteLessEquals = 80;
+        performLimitOffest(appendix, start, end, expectedSize, voteGreaterEquals, voteLessEquals);
+    }
+
+    public void testLimitOffset_4()
+    {
+        String appendix = "_testLimitOffset_4_" + System.currentTimeMillis();
+        int start = 1;
+        int end = 9;
+        int expectedSize = 9;
+        int voteGreaterEquals = 10;
+        int voteLessEquals = 90;
+        performLimitOffest(appendix, start, end, expectedSize, voteGreaterEquals, voteLessEquals);
+    }
+
+    public void testLimitOffset_5()
+    {
+        String appendix = "_testLimitOffset_5_" + System.currentTimeMillis();
+        int start = 1;
+        int end = 12;
+        int expectedSize = 9;
+        int voteGreaterEquals = 10;
+        int voteLessEquals = 90;
+        performLimitOffest(appendix, start, end, expectedSize, voteGreaterEquals, voteLessEquals);
+    }
+
+    public void testLimitOffset_6()
+    {
+        String appendix = "_testLimitOffset_6_" + System.currentTimeMillis();
+        int start = 9;
+        int end = 9;
+        int expectedSize = 1;
+        int voteGreaterEquals = 90;
+        int voteLessEquals = 90;
+        performLimitOffest(appendix, start, end, expectedSize, voteGreaterEquals, voteLessEquals);
+    }
+
+    public void testLimitOffset_7()
+    {
+        String appendix = "_testLimitOffset_7_" + System.currentTimeMillis();
+        int start = 4;
+        int end = 7;
+        int expectedSize = 4;
+        int voteGreaterEquals = 40;
+        int voteLessEquals = 70;
+        performLimitOffest(appendix, start, end, expectedSize, voteGreaterEquals, voteLessEquals);
+    }
+
+    public void testLimitOffset_8()
+    {
+        String appendix = "_testLimitOffset_8_" + System.currentTimeMillis();
+        int start = 3;
+        // don't specify end
+        int end = Query.NO_END_AT_INDEX;
+        int expectedSize = 7;
+        int voteGreaterEquals = 30;
+        int voteLessEquals = 90;
+        performLimitOffest(appendix, start, end, expectedSize, voteGreaterEquals, voteLessEquals);
+    }
+
+    public void testLimitOffset_9()
+    {
+        String appendix = "_testLimitOffset_9_" + System.currentTimeMillis();
+        int start = 9;
+        // don't specify end
+        int end = Query.NO_END_AT_INDEX;
+        int expectedSize = 1;
+        int voteGreaterEquals = 90;
+        int voteLessEquals = 90;
+        performLimitOffest(appendix, start, end, expectedSize, voteGreaterEquals, voteLessEquals);
+    }
+
+    public void performLimitOffest(String appendix, int start, int end,
+                                   int expectedSize,
+                                   int voteGreaterEquals, int voteLessEquals)
+    {
+        insertTestData(appendix);
+
+        // first check query without limit/offset, this returns all Review objects with
+        // 'vote' >= 10 ===> expect 9 objects
+        Criteria crit = new Criteria()
+                        .addGreaterOrEqualThan("vote", new Integer(10))
+                        .addLike("book.title", "%"+appendix);
+        QueryByCriteria query = QueryFactory.newQuery(Review.class, crit);
+        // NOTE: If pagination/limit is used it's strongly recommended to order by
+        // a unique column to avoid problems with different result order
+        // ('vote' isn't unique, thus add PK field)
+        query.addOrderByAscending("vote");
+        query.addOrderByAscending("id");
+        // NOTE: if we use pagination it's mandatory not to query "extents" too,
+        // because else it will end in multiple limit queries (one for each extent)
+        // thus the result will be pagination_size * extents
+        query.setWithExtents(false);
+
+        // check result without limit
+        Collection result = broker.getCollectionByQuery(query);
+        assertEquals(9, result.size());
+        for(Iterator iterator = result.iterator(); iterator.hasNext();)
+        {
+            Review r =  (Review) iterator.next();
+            assertTrue(r.getVote().intValue() >= 10);
+            assertNotNull(r.getBook());
+            assertTrue(r.getBook().getTitle().endsWith(appendix));
+        }
+
+        // now start the real work: perform LIMIT query
+        query = QueryFactory.newQuery(Review.class, crit);
+        // NOTE: If pagination/limit is used it's strongly recommended to order by
+        // a unique column to avoid problems with different result order
+        // ('vote' isn't unique, thus add PK field)
+        query.addOrderByAscending("vote");
+        query.addOrderByAscending("id");
+        // NOTE: if we use pagination it's mandatory not to query "extents" too,
+        // because else it will end in multiple limit queries (one for each extent)
+        // thus the result will be pagination_size * extents
+        query.setWithExtents(false);
+        query.setStartAtIndex(start);
+        query.setEndAtIndex(end);
+        result = broker.getCollectionByQuery(query);
+
+        assertEquals(expectedSize, result.size());
+        for(Iterator iterator = result.iterator(); iterator.hasNext();)
+        {
+            Review r =  (Review) iterator.next();
+            // we skip the first one thus we expect 60
+            assertTrue("Expected Review.vote >=" + voteGreaterEquals + " but get: "
+                    + r.getVote().intValue(), r.getVote().intValue() >= voteGreaterEquals);
+            assertTrue("Expected Review.vote <=" + voteLessEquals +" but get: "
+                    + r.getVote().intValue(), r.getVote().intValue() <= voteLessEquals);
+            assertNotNull(r.getBook());
+            assertTrue(r.getBook().getTitle().endsWith(appendix));
+            //System.out.println("r: " + r);
+        }
+
+        deleteTestData(appendix);
+    }
+
+    /**
+     * Creates and store multiple Article objects with increasing
+     * Article.stock value (starting with 1).
+     */
+    private List createArticles(String name, int count)
+    {
+        List result = new ArrayList();
+        broker.beginTransaction();
+        for(int i=1; i<count + 1; i++)
+        {
+            Article a = createArticle(null, name);
+            a.setStock(i);
+            broker.store(a);
+            result.add(a);
+        }
+        broker.commitTransaction();
+        return result;
+    }
+
+    public void pagingPositionTest(String name, int articleCount, int startIndex, int endIndex,
+                                   int absoluteIndex, final int expectedStockValue, boolean allowRelativePlus1)
+    {
+//        String name = "testPagingPosition_1_" + System.currentTimeMillis();
+//        int articleCount = 20;
+//        int startIndex = 10;
+//        int endIndex = 14;
+//        int absoluteIndex = 1;
+//        int expectedStockValue = 10;
+
+        boolean supportsScrollableResultSet = broker.serviceConnectionManager().getConnectionDescriptor().getJdbcLevel() > 1.0;
+        boolean old = broker.serviceConnectionManager().getConnectionDescriptor().isNativeLimitOffset();
+
+        createArticles(name, articleCount);
+
+        Collection fullColl;
+        OJBIterator ojbIterator;
+        InterfaceArticle article;
+
+        // All Articles index in range
+        Criteria crit = new Criteria().addEqualTo("articleName", name);
+        QueryByCriteria query = QueryFactory.newQuery(Article.class, crit);
+        // primary order clause, not unique!!
+        query.addOrderByAscending("stock");
+        query.setWithExtents(false);
+        // get all created Article objects
+        fullColl = broker.getCollectionByQuery(query);
+        assertEquals(articleCount, fullColl.size());
+
+
+        try
+        {
+            // -------------------------------------------------------------
+            // expect RsIterator instance, without extents, nativeLimit=true
+            // -------------------------------------------------------------
+            query = QueryFactory.newQuery(Article.class, crit);
+            // NOTE: If pagination/limit is used it's strongly recommended to order by
+            // a unique column to avoid problems with different result order
+            query.addOrderByAscending("articleId");
+            // if we use pagination it's mandatory not to query "extents" too,
+            // because else it will end in multiple limit queries (one for each extent)
+            // thus the result will be pagination_size * extents
+            query.setWithExtents(false);
+            // limited query
+            query.setStartAtIndex(startIndex);
+            query.setEndAtIndex(endIndex);
+            // use native DB paging if supported
+            broker.serviceConnectionManager().getConnectionDescriptor().setNativeLimitOffset(true);
+
+            ojbIterator = (OJBIterator) broker.getIteratorByQuery(query);
+            // we expect the default iterator class
+            assertTrue(broker.serviceConnectionManager().getSupportedPlatform().supportsOffset() ?
+                    ojbIterator instanceof RsIterator : ojbIterator instanceof PagingIterator);
+
+//            System.out.println("#### result for (start=" + startIndex + ",end=" + endIndex
+//                    +"), absoluteIndex="+ absoluteIndex + ", expected="+expectedStockValue+": "
+//                    + new ArrayList(broker.getCollectionByQuery(query)));
+
+            // jump to index
+            ojbIterator.absolute(absoluteIndex);
+            article = (InterfaceArticle) ojbIterator.next();
+            assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+            if(supportsScrollableResultSet)
+            {
+                // jump back
+                ojbIterator.relative(-1);
+                article = (InterfaceArticle)ojbIterator.next();
+                assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                // jump back
+                ojbIterator.relative(-1);
+                assertTrue(ojbIterator.hasNext());
+                article = (InterfaceArticle)ojbIterator.next();
+                assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                if(allowRelativePlus1)
+                {
+                    // jump forward 1
+                    ojbIterator.relative(1);
+                    article = (InterfaceArticle)ojbIterator.next();
+                    assertEquals("Expected Article stock=" + (expectedStockValue + 2), expectedStockValue + 2, article.getStock());
+
+                    // jump back two
+                    ojbIterator.relative(-3);
+                    article = (InterfaceArticle)ojbIterator.next();
+                    assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                }
+            }
+            // manually release used resources
+            ojbIterator.releaseDbResources();
+
+
+            // -------------------------------------------------------------
+            // expect PagingIterator instance, without extents, nativeLimit=false
+            // -------------------------------------------------------------
+            query = QueryFactory.newQuery(Article.class, crit);
+            query.setWithExtents(false);
+            query.setStartAtIndex(startIndex);
+            query.setEndAtIndex(endIndex);
+            broker.serviceConnectionManager().getConnectionDescriptor().setNativeLimitOffset(false);
+
+            ojbIterator = (OJBIterator)broker.getIteratorByQuery(query);
+            // we expect a paging iterator instance
+            assertTrue(ojbIterator instanceof PagingIterator);
+
+            // jump to index
+            ojbIterator.absolute(absoluteIndex);
+            article = (InterfaceArticle)ojbIterator.next();
+            assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+            if(supportsScrollableResultSet)
+            {
+                // jump back
+                ojbIterator.relative(-1);
+                article = (InterfaceArticle)ojbIterator.next();
+                assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                // jump back
+                ojbIterator.relative(-1);
+                assertTrue(ojbIterator.hasNext());
+                article = (InterfaceArticle)ojbIterator.next();
+                assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                if(allowRelativePlus1)
+                {
+                    // jump forward 1
+                    ojbIterator.relative(1);
+                    article = (InterfaceArticle)ojbIterator.next();
+                    assertEquals("Expected Article stock=" + (expectedStockValue + 2), expectedStockValue + 2, article.getStock());
+
+                    // jump back two
+                    ojbIterator.relative(-3);
+                    article = (InterfaceArticle)ojbIterator.next();
+                    assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                }
+            }
+            // manually release used resources
+            ojbIterator.releaseDbResources();
+
+
+            // -------------------------------------------------------------
+            // expect ChainingIterator instance, with extents, nativeLimit=true
+            // -------------------------------------------------------------
+            query = QueryFactory.newQuery(Article.class, crit);
+            // now we want all results with extents, in this case OJB
+            // will use a chaining iterator
+            query.setWithExtents(true);
+            query.setStartAtIndex(startIndex);
+            query.setEndAtIndex(endIndex);
+            broker.serviceConnectionManager().getConnectionDescriptor().setNativeLimitOffset(true);
+            ojbIterator = (OJBIterator)broker.getIteratorByQuery(query);
+            assertTrue(ojbIterator instanceof ChainingIterator);
+            // jump to index
+            ojbIterator.absolute(absoluteIndex);
+            article = (InterfaceArticle)ojbIterator.next();
+            assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+            if(supportsScrollableResultSet)
+            {
+                // jump back
+                ojbIterator.relative(-1);
+                article = (InterfaceArticle)ojbIterator.next();
+                assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                // jump back
+                ojbIterator.relative(-1);
+                assertTrue(ojbIterator.hasNext());
+                article = (InterfaceArticle)ojbIterator.next();
+                assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                if(allowRelativePlus1)
+                {
+                    // jump forward 1
+                    ojbIterator.relative(1);
+                    article = (InterfaceArticle)ojbIterator.next();
+                    assertEquals("Expected Article stock=" + (expectedStockValue + 2), expectedStockValue + 2, article.getStock());
+
+                    // jump back two
+                    ojbIterator.relative(-3);
+                    article = (InterfaceArticle)ojbIterator.next();
+                    assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                }
+            }
+            // manually release used resources
+            ojbIterator.releaseDbResources();
+
+
+            // -------------------------------------------------------------
+            // expect ChainingIterator instance, with extents, nativeLimit=false
+            // -------------------------------------------------------------
+            query = QueryFactory.newQuery(Article.class, crit);
+            // now we want all results with extents, in this case OJB
+            // will use a chaining iterator
+            query.setWithExtents(true);
+            query.setStartAtIndex(startIndex);
+            query.setEndAtIndex(endIndex);
+            broker.serviceConnectionManager().getConnectionDescriptor().setNativeLimitOffset(false);
+            ojbIterator = (OJBIterator)broker.getIteratorByQuery(query);
+            assertTrue("Expect instance of "+ClassUtils.getShortClassName(ChainingIterator.class)
+                    + " but was " + ojbIterator, ojbIterator instanceof ChainingIterator);
+
+            // jump to index
+            ojbIterator.absolute(absoluteIndex);
+            article = (InterfaceArticle)ojbIterator.next();
+            assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+            if(supportsScrollableResultSet)
+            {
+                // jump back
+                ojbIterator.relative(-1);
+                article = (InterfaceArticle)ojbIterator.next();
+                assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                // jump back
+                ojbIterator.relative(-1);
+                assertTrue(ojbIterator.hasNext());
+                article = (InterfaceArticle)ojbIterator.next();
+                assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                if(allowRelativePlus1)
+                {
+                    // jump forward 1
+                    ojbIterator.relative(1);
+                    article = (InterfaceArticle)ojbIterator.next();
+                    assertEquals("Expected Article stock=" + (expectedStockValue + 2), expectedStockValue + 2, article.getStock());
+
+                    // jump back two
+                    ojbIterator.relative(-3);
+                    article = (InterfaceArticle)ojbIterator.next();
+                    assertEquals("Expected Article stock=" + expectedStockValue, expectedStockValue, article.getStock());
+                }
+            }
+            // manually release used resources
+            ojbIterator.releaseDbResources();
+        }
+        finally
+        {
+            broker.serviceConnectionManager().getConnectionDescriptor().setNativeLimitOffset(old);
+        }
+    }
+
+    public void testPagingPosition_1()
+    {
+        String name = "testPagingPosition_1_" + System.currentTimeMillis();
+        int articleCount = 20;
+        int startIndex = 10;
+        int endIndex = 14;
+        // move to first position
+        int absoluteIndex = 1;
+        int expectedStockValue = 10;
+        boolean allowRelativePlusOneCall = true;
+
+        pagingPositionTest(name, articleCount, startIndex, endIndex, absoluteIndex, expectedStockValue, allowRelativePlusOneCall);
+    }
+
+    public void testPagingPosition_2()
+    {
+        String name = "testPagingPosition_2_" + System.currentTimeMillis();
+        int articleCount = 20;
+        int startIndex = 10;
+        int endIndex = 15;
+        // move to third position
+        int absoluteIndex = 3;
+        int expectedStockValue = 12;
+        boolean allowRelativePlusOneCall = true;
+
+        pagingPositionTest(name, articleCount, startIndex, endIndex, absoluteIndex, expectedStockValue, allowRelativePlusOneCall);
+    }
+
+    public void testPagingPosition_3()
+    {
+        String name = "testPagingPosition_3_" + System.currentTimeMillis();
+        int articleCount = 20;
+        int startIndex = 10;
+        int endIndex = 14;
+        // move to last position
+        int absoluteIndex = 5;
+        int expectedStockValue = 14;
+        boolean allowRelativePlusOneCall = false;
+
+        pagingPositionTest(name, articleCount, startIndex, endIndex, absoluteIndex, expectedStockValue, allowRelativePlusOneCall);
+    }
+
+    public void testPagingPosition_4()
+    {
+        String name = "testPagingPosition_4_" + System.currentTimeMillis();
+        int articleCount = 20;
+        int startIndex = 10;
+        int endIndex = 14;
+        // move to last position
+        int absoluteIndex = -1;
+        int expectedStockValue = 14;
+        boolean allowRelativePlusOneCall = false;
+
+        pagingPositionTest(name, articleCount, startIndex, endIndex, absoluteIndex, expectedStockValue, allowRelativePlusOneCall);
+    }
+
+    public void testPagingPosition_5()
+    {
+        String name = "testPagingPosition_5_" + System.currentTimeMillis();
+        int articleCount = 20;
+        int startIndex = 10;
+        int endIndex = 14;
+        // move to first position
+        int absoluteIndex = -5;
+        int expectedStockValue = 10;
+        boolean allowRelativePlusOneCall = true;
+
+        pagingPositionTest(name, articleCount, startIndex, endIndex, absoluteIndex, expectedStockValue, allowRelativePlusOneCall);
+    }
+
+    
+
+    public void testChainingIteratorPaging()
+    {
+        String name = "testChainingIteratorPaging_" + System.currentTimeMillis();
+        int count = 27;
+
+        List result = new ArrayList();
+        broker.beginTransaction();
+        for(int i=0; i<count; i++)
+        {
+            InterfaceArticle a;
+            if((i/3) % 3 == 0) a = new Article();
+            else if((i/3) % 3 == 1) a = new CdArticle();
+            else a = new BookArticle();
+            a.setArticleName(name);
+            a.setStock(i);
+            //System.out.println("store " + i + ": " + ClassUtils.getShortClassName(a.getClass()) + "[stock="+a.getStock()+"]");
+            broker.store(a);
+            result.add(a);
+        }
+        broker.commitTransaction();
+
+        // All Articles index in range
+        Criteria crit = new Criteria().addEqualTo("articleName", name);
+        QueryByCriteria query = QueryFactory.newQuery(Article.class, crit);
+        query.addOrderByAscending("stock");
+        query.addOrderByAscending("articleId");
+        query.setWithExtents(true);
+
+        int fullSize = broker.getCollectionByQuery(query).size();
+        assertEquals(count, fullSize);
+
+        // limit query to main class Article objects
+        query = QueryFactory.newQuery(Article.class, crit);
+        query.addOrderByAscending("stock");
+        query.addOrderByAscending("articleId");
+        query.setWithExtents(true);
+        query.setStartAtIndex(1);
+        query.setEndAtIndex(1);
+        OJBIterator ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
+        int counter = 0;
+        while(ojbIter.hasNext())
+        {
+            InterfaceArticle o = (InterfaceArticle) ojbIter.next();
+            //System.out.println("o: " + o);
+            assertEquals(0, o.getStock() % 3);
+            ++counter;
+        }
+        assertEquals(3, counter);
+
+
+        query = QueryFactory.newQuery(Article.class, crit);
+        query.addOrderByAscending("stock");
+        query.addOrderByAscending("articleId");
+        query.setWithExtents(true);
+        query.setStartAtIndex(7);
+        query.setEndAtIndex(7);
+        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
+        counter = 0;
+        while(ojbIter.hasNext())
+        {
+            ++counter;
+            InterfaceArticle o = (InterfaceArticle) ojbIter.next();
+            //System.out.println("o: " + o);
+            assertEquals(0, o.getStock()%3);
+        }
+        assertEquals(3, counter);
+
+
+        query = QueryFactory.newQuery(Article.class, crit);
+        query.addOrderByAscending("stock");
+        query.addOrderByAscending("articleId");
+        query.setWithExtents(true);
+        query.setStartAtIndex(3);
+        query.setEndAtIndex(4);
+        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
+        counter = 0;
+        while(ojbIter.hasNext())
+        {
+            ++counter;
+            InterfaceArticle o = (InterfaceArticle) ojbIter.next();
+            //System.out.println("o: " + o);
+            int modValue = o.getStock() % 3;
+            assertTrue(modValue == 0 || modValue == 2);
+        }
+        assertEquals(6, counter);
+
+        query = QueryFactory.newQuery(Article.class, crit);
+        query.addOrderByAscending("stock");
+        query.addOrderByAscending("articleId");
+        query.setWithExtents(true);
+        query.setStartAtIndex(7);
+        query.setEndAtIndex(7);
+        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
+        counter = 0;
+        while(ojbIter.hasNext())
+        {
+            ++counter;
+            InterfaceArticle o = (InterfaceArticle) ojbIter.next();
+            //System.out.println("o: " + o);
+            assertEquals(0, o.getStock()%3);
+        }
+        assertEquals(3, counter);
+    }
+
+    public void testPagingIndicesOutOfRange()
+    {
+        OJBIterator ojbIter;
+        QueryByCriteria query;
+        int fullSize;
+
+        // All Articles index out of  range
+        query = QueryFactory.newQuery(Article.class, new Criteria());
+        fullSize = broker.getCollectionByQuery(query).size();
+
+        // NOTE: If pagination/limit is used it's strongly recommended to order by
+        // a unique column to avoid problems with different result order
+        query.addOrderByAscending("articleId");
+        // if we use pagination it's mandatory not to query "extents" too,
+        // because else it will end in multiple limit queries (one for each extent)
+        // thus the result will be pagination_size * extents
+        query.setWithExtents(false);
+        query.setStartAtIndex(fullSize + 5);
+        query.setEndAtIndex(fullSize + 14);
+        ojbIter = (OJBIterator) broker.getIteratorByQuery(query);
+        assertEquals("indices out of range expecting 0 rows", 0,ojbIter.size());
+        ojbIter.releaseDbResources();
+    }
+
+    public void testPagingEndIndexOutOfRange()
+    {
+        OJBIterator ojbIter;
+        Criteria crit;
+        QueryByCriteria query;
+        int fullSize;
+
+        // All Articles index out of  range
+        crit = new Criteria();
+        query = QueryFactory.newQuery(Article.class, crit);
+        // NOTE: If pagination/limit is used it's strongly recommended to order by
+        // a unique column to avoid problems with different result order
+        query.addOrderByAscending("articleId");
+        // if we use pagination it's mandatory not to query "extents" too,
+        // because else it will end in multiple limit queries (one for each extent)
+        // thus the result will be pagination_size * extents
+        query.setWithExtents(false);
+        fullSize = broker.getCollectionByQuery(query).size();
+
+        query.setStartAtIndex(fullSize - 9);
+        query.setEndAtIndex(fullSize + 9);
+        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
+        assertEquals("end index out of range expecting 0 rows", 10,ojbIter.size());
+        ojbIter.releaseDbResources();
+    }
+
+    public void testPagingEmptyIterator()
+    {
+        OJBIterator ojbIter;
+        Criteria crit;
+        QueryByCriteria query;
+
+        // looking for inexistent Article
+        crit = new Criteria();
+        crit.addEqualTo("articleId",new Integer(-777));
+        query = QueryFactory.newQuery(Article.class, crit);
+        int fullSize = broker.getCollectionByQuery(query).size();
+
+        // NOTE: If pagination/limit is used it's strongly recommended to order by
+        // a unique column to avoid problems with different result order
+        query.addOrderByAscending("articleId");
+        // if we use pagination it's mandatory not to query "extents" too,
+        // because else it will end in multiple limit queries (one for each extent)
+        // thus the result will be pagination_size * extents
+        query.setWithExtents(false);
+        query.setStartAtIndex(10);
+        query.setEndAtIndex(14);
+        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
+        assertEquals("index 10 - 14 expecting 0 rows for empty iterator", 0,ojbIter.size());
+        ojbIter.releaseDbResources();
+    }
+
+    private Article createArticle(ProductGroup group, String name)
+    {
+        Article a = new Article();
+        a.setArticleName(name);
+        a.setIsSelloutArticle(true);
+        a.setMinimumStock(100);
+        a.setOrderedUnits(17);
+        a.setPrice(0.45);
+        if(group != null)
+        {
+            a.setProductGroup(group);
+            group.add(a);
+        }
+        a.setStock(234);
+        a.setSupplierId(4);
+        a.setUnit("bottle");
+        return a;
+    }
+
+
+
+
+    //=======================================================
+    // inner test classes
+    //=======================================================
+    /*
+    NOTE: Take care of endless loops when change override toString method!!!!
+    */
+    public static class Book implements Serializable
+    {
+        private Integer id;
+        private String title;
+        private Date publicationDate;
+        private byte[] cover;
+        private Integer version;
+        private Integer fkPublisher;
+
+        private List authors;
+        private List reviews;
+        private Publisher publisher;
+
+        public Book()
+        {
+        }
+
+        public Book(String title, Date publicationDate, byte[] cover)
+        {
+            this.title = title;
+            this.publicationDate = publicationDate;
+            this.cover = cover;
+        }
+
+        public String toString()
+        {
+            return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                    .append("id", id)
+                    .append("title", title)
+                    .append("publicationDate", publicationDate)
+                    .append("version", version)
+                    .append("fkPublisher", fkPublisher)
+                    .append("cover", cover)
+                    .append("authors.size", authors != null ? authors.size() : 0)
+                    .append("reviews.size", reviews != null ? reviews.size() : 0)
+                    .append("publisher", publisher)
+                    .toString();
+        }
+
+        public void addAuthor(Author author)
+        {
+            if(authors == null)
+            {
+                authors = new ArrayList();
+            }
+            authors.add(author);
+        }
+
+        public void addReview(Review review)
+        {
+            if(reviews == null)
+            {
+                reviews = new ArrayList();
+            }
+            reviews.add(review);
+        }
+
+        public boolean removeReview(Review review)
+        {
+            if(reviews != null) return reviews.remove(review);
+            else return false;
+        }
+
+        public Integer getId()
+        {
+            return id;
+        }
+
+        public void setId(Integer id)
+        {
+            this.id = id;
+        }
+
+        public String getTitle()
+        {
+            return title;
+        }
+
+        public void setTitle(String title)
+        {
+            this.title = title;
+        }
+
+        public Date getPublicationDate()
+        {
+            return publicationDate;
+        }
+
+        public void setPublicationDate(Date publicationDate)
+        {
+            this.publicationDate = publicationDate;
+        }
+
+        public byte[] getCover()
+        {
+            return cover;
+        }
+
+        public void setCover(byte[] cover)
+        {
+            this.cover = cover;
+        }
+
+        public Integer getVersion()
+        {
+            return version;
+        }
+
+        public void setVersion(Integer version)
+        {
+            this.version = version;
+        }
+
+        public List getAuthors()
+        {
+            return authors;
+        }
+
+        public void setAuthors(List authors)
+        {
+            this.authors = authors;
+        }
+
+        public List getReviews()
+        {
+            return reviews;
+        }
+
+        public void setReviews(List reviews)
+        {
+            this.reviews = reviews;
+        }
+
+        public Publisher getPublisher()
+        {
+            return publisher;
+        }
+
+        public void setPublisher(Publisher publisher)
+        {
+            this.publisher = publisher;
+        }
+    }
+
+    public static class Author implements Serializable
+    {
+        private Integer id;
+        private String name;
+        private List books;
+        private Integer version;
+        private Publisher publisher;
+        private Integer fkPublisher;
+
+        public Author()
+        {
+        }
+
+        public Author(String name, List books)
+        {
+            this.name = name;
+            this.books = books;
+        }
+
+        public void addBook(Book book)
+        {
+            if(books == null)
+            {
+                books = new ArrayList();
+            }
+            books.add(book);
+        }
+
+        public Integer getId()
+        {
+            return id;
+        }
+
+        public void setId(Integer id)
+        {
+            this.id = id;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public void setName(String name)
+        {
+            this.name = name;
+        }
+
+        public Integer getVersion()
+        {
+            return version;
+        }
+
+        public void setVersion(Integer version)
+        {
+            this.version = version;
+        }
+
+        public List getBooks()
+        {
+            return books;
+        }
+
+        public void setBooks(List books)
+        {
+            this.books = books;
+        }
+
+        public Publisher getPublisher()
+        {
+            return publisher;
+        }
+
+        public void setPublisher(Publisher publisher)
+        {
+            this.publisher = publisher;
+        }
+    }
+
+    public static interface Publisher extends Serializable
+    {
+        public Integer getId();
+        public void setId(Integer id);
+        public String getName();
+        public void setName(String name);
+        public Integer getVersion();
+        public void setVersion(Integer version);
+        public List getAuthors();
+        public void setAuthors(List authors);
+        public void addAuthor(Author author);
+        public List getBooks();
+        public void setBooks(List books);
+        public void addBook(Book book);
+    }
+
+    public static class PublisherImpl implements Publisher
+    {
+        private Integer id;
+        private String name;
+        private Integer version;
+        private List authors;
+        private List books;
+
+        public PublisherImpl()
+        {
+        }
+
+        public PublisherImpl(String name)
+        {
+            this.name = name;
+        }
+
+        public Integer getId()
+        {
+            return id;
+        }
+
+        public void setId(Integer id)
+        {
+            this.id = id;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public void setName(String name)
+        {
+            this.name = name;
+        }
+
+        public Integer getVersion()
+        {
+            return version;
+        }
+
+        public void setVersion(Integer version)
+        {
+            this.version = version;
+        }
+
+        public List getAuthors()
+        {
+            return authors;
+        }
+
+        public void setAuthors(List authors)
+        {
+            this.authors = authors;
+        }
+
+        public void addAuthor(Author author)
+        {
+            if(authors == null)
+            {
+                authors = new ArrayList();
+            }
+            if(! authors.contains(author)) authors.add(author);
+        }
+
+        public List getBooks()
+        {
+            return books;
+        }
+
+        public void setBooks(List books)
+        {
+            this.books = books;
+        }
+
+        public void addBook(Book book)
+        {
+            if(books == null)
+            {
+                books = new ArrayList();
+            }
+            if(! books.contains(book)) books.add(book);
+        }
+    }
+
+    public static class Review implements Serializable
+    {
+        private Integer id;
+        private Integer vote;
+        private String summary;
+        private Integer fkBook;
+        private Integer version;
+        private Author author;
+        private Book book;
+
+        public Review()
+        {
+        }
+
+        public Review(String summary, Integer vote, Book book)
+        {
+            this.summary = summary;
+            this.vote = vote;
+            this.book = book;
+        }
+
+        public Review(String summary, Integer vote)
+        {
+            this.summary = summary;
+            this.vote = vote;
+        }
+
+        public Review(String summary)
+        {
+            this.summary = summary;
+        }
+
+        public Integer getId()
+        {
+            return id;
+        }
+
+        public Integer getVote()
+        {
+            return vote;
+        }
+
+        public void setVote(Integer vote)
+        {
+            this.vote = vote;
+        }
+
+        public void setId(Integer id)
+        {
+            this.id = id;
+        }
+
+        public Integer getFkBook()
+        {
+            return fkBook;
+        }
+
+        public void setFkBook(Integer fkBook)
+        {
+            this.fkBook = fkBook;
+        }
+
+        public String getSummary()
+        {
+            return summary;
+        }
+
+        public void setSummary(String summary)
+        {
+            this.summary = summary;
+        }
+
+        public Integer getVersion()
+        {
+            return version;
+        }
+
+        public void setVersion(Integer version)
+        {
+            this.version = version;
+        }
+
+        public Author getAuthor()
+        {
+            return author;
+        }
+
+        public void setAuthor(Author author)
+        {
+            this.author = author;
+        }
+
+        public Book getBook()
+        {
+            return book;
+        }
+
+        public void setBook(Book book)
+        {
+            this.book = book;
+        }
+
+        public boolean equals(Object obj)
+        {
+            boolean result = false;
+            if(obj instanceof Review)
+            {
+                Review other = (Review) obj;
+                result = new EqualsBuilder()
+                        .append(id, other.id)
+                        .append(summary, other.summary)
+                        .append(version, other.version)
+                        .append(fkBook, other.fkBook)
+                        .append(author, other.author)
+                        .isEquals();
+            }
+            return result;
+        }
+
+        public String toString()
+        {
+            return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE, false);
+        }
+    }
+
+}

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PersistenceBrokerTest.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PersistenceBrokerTest.java?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PersistenceBrokerTest.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/PersistenceBrokerTest.java Thu Mar  1 16:52:47 2007
@@ -864,12 +864,14 @@
     public void testGetCollectionByQueryWithStartAndEnd() throws Exception
     {
         String name = "testGetCollectionByQueryWithStartAndEnd_" + System.currentTimeMillis();
+
         Criteria criteria = new Criteria();
         criteria.addEqualTo("articleName", name);
         //            criteria.addEqualTo("isSelloutArticle", new Boolean(true));
-        Query query = QueryFactory.newQuery(Article.class, criteria);
+        QueryByCriteria query = QueryFactory.newQuery(Article.class, criteria);
         Collection col = broker.getCollectionByQuery(query);
         assertEquals("size of collection should be zero", 0, col.size());
+
         //2. insert 5 matching items
         broker.beginTransaction();
         Article a1 = createArticle(null, name);
@@ -883,8 +885,15 @@
         Article a5 = createArticle(null, name);
         broker.store(a5);
         broker.commitTransaction();
-
         broker.clearCache();
+
+        // NOTE: If pagination/limit is used it's strongly recommended to order by
+        // a unique column to avoid problems with different result order
+        query.addOrderByAscending("articleId");
+        // if we use pagination it's mandatory not to query "extents" too,
+        // because else it will end in multiple limit queries (one for each extent)
+        // thus the result will be pagination_size * extents
+        query.setWithExtents(false);
         // 3. set query start and end
         query.setStartAtIndex(2);
         query.setEndAtIndex(5);
@@ -903,6 +912,13 @@
             assertTrue("Id should be a number of the generated articles", range.containsInteger(id));
         }
 
+        // NOTE: If pagination/limit is used it's strongly recommended to order by
+        // a unique column to avoid problems with different result order
+        query.addOrderByAscending("articleId");
+        // if we use pagination it's mandatory not to query "extents" too,
+        // because else it will end in multiple limit queries (one for each extent)
+        // thus the result will be pagination_size * extents
+        query.setWithExtents(false);
         // read one item only
         // 1. set query start equals end
         query.setStartAtIndex(4);
@@ -1500,142 +1516,6 @@
         iterSize = ojbIter.size();
 
         assertEquals("collSize == iterSize", collSize , iterSize);
-        ojbIter.releaseDbResources();
-    }
-
-    public void testPaging()
-    {
-        OJBIterator ojbIter;
-        Criteria crit;
-        QueryByCriteria query;
-
-        // All Articles index in range
-        crit = new Criteria();
-        query = QueryFactory.newQuery(Article.class, crit);
-        int fullSize = broker.getCollectionByQuery(query).size();
-
-        query.setStartAtIndex(10);
-        query.setEndAtIndex(14);
-        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
-        assertEquals("index 10 - 14 expecting 5 rows", 5,ojbIter.size());
-        ojbIter.releaseDbResources();
-    }
-
-    public void testPagingPosition()
-    {
-        String name = "testPagingPosition_" + System.currentTimeMillis();
-        broker.beginTransaction();
-        for(int i=1; i<21; i++)
-        {
-            Article a = createArticle(null, name);
-            a.setStock(i);
-            broker.store(a);
-        }
-        broker.commitTransaction();
-
-        OJBIterator ojbIter;
-        Criteria crit;
-        QueryByCriteria query;
-        Collection fullColl, pagedColl;
-        InterfaceArticle article;
-        
-        // All Articles index in range
-        crit = new Criteria();
-        crit.addEqualTo("articleName", name);
-        query = QueryFactory.newQuery(Article.class, crit);
-        query.addOrderByAscending("stock");
-        fullColl = broker.getCollectionByQuery(query);
-        assertEquals(20, fullColl.size());
-
-        // limited query
-        query.setStartAtIndex(10);
-        query.setEndAtIndex(14);
-        pagedColl = broker.getCollectionByQuery(query);
-                      
-        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
-        
-        assertEquals("collection- and iterator-size must match", pagedColl.size(), ojbIter.size());
-        assertEquals("index 10 - 14 expecting 5 rows", 5,ojbIter.size());
-        
-        ojbIter.absolute(2);
-        article = (InterfaceArticle)ojbIter.next();
-        assertEquals("Article stock=12", article.getStock(), 12);
-        
-        ojbIter.relative(-1);
-        article = (InterfaceArticle)ojbIter.next();
-        assertEquals("Article id=12", article.getStock(), 12);
-
-        ojbIter.relative(-1);
-        article = (InterfaceArticle)ojbIter.next();
-        assertEquals("Article id=12", article.getStock(), 12);
-        
-        // last
-        ojbIter.absolute(12);
-        article = (InterfaceArticle)ojbIter.next();
-        assertEquals("Article id=15", article.getStock(), 15);
-
-        // first
-        ojbIter.absolute(-12);
-        article = (InterfaceArticle)ojbIter.next();
-        assertEquals("Article id=10", article.getStock(), 10);
-        
-        ojbIter.releaseDbResources();
-    }
-    
-    public void testPagingIndicesOutOfRange()
-    {
-        OJBIterator ojbIter;
-        Criteria crit;
-        QueryByCriteria query;
-        int fullSize;
-
-        // All Articles index out of  range
-        crit = new Criteria();
-        query = QueryFactory.newQuery(Article.class, crit);
-        fullSize = broker.getCollectionByQuery(query).size();
-
-        query.setStartAtIndex(fullSize + 5);
-        query.setEndAtIndex(fullSize + 14);
-        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
-        assertEquals("indices out of range expecting 0 rows", 0,ojbIter.size());
-        ojbIter.releaseDbResources();
-    }
-
-    public void testPagingEndIndexOutOfRange()
-    {
-        OJBIterator ojbIter;
-        Criteria crit;
-        QueryByCriteria query;
-        int fullSize;
-
-        // All Articles index out of  range
-        crit = new Criteria();
-        query = QueryFactory.newQuery(Article.class, crit);
-        fullSize = broker.getCollectionByQuery(query).size();
-
-        query.setStartAtIndex(fullSize - 9);
-        query.setEndAtIndex(fullSize + 9);
-        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
-        assertEquals("end index out of range expecting 10 rows", 10,ojbIter.size());
-        ojbIter.releaseDbResources();
-    }
-
-    public void testPagingEmptyIterator()
-    {
-        OJBIterator ojbIter;
-        Criteria crit;
-        QueryByCriteria query;
-
-        // looking for inexistent Article
-        crit = new Criteria();
-        crit.addEqualTo("articleId",new Integer(-777));
-        query = QueryFactory.newQuery(Article.class, crit);
-        int fullSize = broker.getCollectionByQuery(query).size();
-
-        query.setStartAtIndex(10);
-        query.setEndAtIndex(14);
-        ojbIter = (OJBIterator)broker.getIteratorByQuery(query);
-        assertEquals("index 10 - 14 expecting 0 rows for empty iterator", 0,ojbIter.size());
         ojbIter.releaseDbResources();
     }
 }

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityHsqlTest.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityHsqlTest.java?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityHsqlTest.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityHsqlTest.java Thu Mar  1 16:52:47 2007
@@ -38,7 +38,8 @@
     protected void initDBDependend() throws Exception
     {
         dropConstraintMainTable = "ALTER TABLE NATIVE_MAIN_OBJECT DROP CONSTRAINT MAIN_REF_FK";
-        createMainTable = "CREATE TABLE NATIVE_MAIN_OBJECT(NATIVE_ID IDENTITY NOT NULL PRIMARY KEY, REF_ID int,NAME VARCHAR(250))";
+        createMainTable = "CREATE TABLE NATIVE_MAIN_OBJECT(NATIVE_ID IDENTITY NOT NULL PRIMARY KEY, CLASS_NAME VARCHAR(250), REF_ID int,NAME VARCHAR(250))";
+        createDerivedTable = "CREATE TABLE NATIVE_DERIVED_OBJECT(NATIVE_ID IDENTITY NOT NULL PRIMARY KEY, CLASS_NAME VARCHAR(250), REF_ID int,NAME VARCHAR(250))";
         createRefTable = "CREATE TABLE NATIVE_REFERENCE_OBJECT (NATIVE_ID IDENTITY NOT NULL PRIMARY KEY," +
             " NAME VARCHAR(250), OJB_CONCRETE_CLASS VARCHAR(250), FK_ID int, REF_ID int, SINGLE_REF_FK BIGINT" +
             " , FOREIGN KEY (FK_ID) REFERENCES NATIVE_MAIN_OBJECT (NATIVE_ID) )";

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMaxDBTest.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMaxDBTest.java?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMaxDBTest.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMaxDBTest.java Thu Mar  1 16:52:47 2007
@@ -40,7 +40,9 @@
     {
         dropConstraintMainTable = "ALTER TABLE NATIVE_MAIN_OBJECT DROP FOREIGN KEY MAIN_REF_FK";
         createMainTable = "CREATE TABLE NATIVE_MAIN_OBJECT" +
-                "(NATIVE_ID SERIAL PRIMARY KEY, REF_ID FIXED(10), NAME VARCHAR(250))";
+                "(NATIVE_ID SERIAL PRIMARY KEY, CLASS_NAME VARCHAR(250), REF_ID FIXED(10), NAME VARCHAR(250))";
+        createDerivedTable = "CREATE TABLE NATIVE_DERIVED_OBJECT" +
+                "(NATIVE_ID SERIAL PRIMARY KEY, CLASS_NAME VARCHAR(250), REF_ID FIXED(10), NAME VARCHAR(250))";
         createRefTable =
             "CREATE TABLE NATIVE_REFERENCE_OBJECT(NATIVE_ID SERIAL PRIMARY KEY," +
             " NAME VARCHAR(250), OJB_CONCRETE_CLASS VARCHAR(250), FK_ID FIXED(10), REF_ID FIXED(10)," +

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMySqlTest.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMySqlTest.java?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMySqlTest.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityMySqlTest.java Thu Mar  1 16:52:47 2007
@@ -38,7 +38,12 @@
     protected void initDBDependend() throws Exception
     {
         dropConstraintMainTable = "ALTER TABLE NATIVE_MAIN_OBJECT DROP FOREIGN KEY MAIN_REF_FK";
-        createMainTable = "CREATE TABLE NATIVE_MAIN_OBJECT(NATIVE_ID int(11) NOT NULL PRIMARY KEY auto_increment,REF_ID int(11),NAME VARCHAR(250))";
+        createMainTable = "CREATE TABLE NATIVE_MAIN_OBJECT(" +
+                "NATIVE_ID int(11) NOT NULL PRIMARY KEY auto_increment," +
+                "CLASS_NAME VARCHAR(250),REF_ID int(11),NAME VARCHAR(250))";
+        createDerivedTable = "CREATE TABLE NATIVE_DERIVED_OBJECT(" +
+                "NATIVE_ID int(11) NOT NULL PRIMARY KEY auto_increment," +
+                "CLASS_NAME VARCHAR(250),REF_ID int(11),NAME VARCHAR(250))";
         createRefTable =
             "CREATE TABLE NATIVE_REFERENCE_OBJECT (NATIVE_ID int(11) NOT NULL PRIMARY KEY auto_increment," +
             " NAME VARCHAR(250), OJB_CONCRETE_CLASS VARCHAR(250), FK_ID int, REF_ID int(11), SINGLE_REF_FK BIGINT" +

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityTest.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityTest.java?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityTest.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/sequence/DatabaseIdentityTest.java Thu Mar  1 16:52:47 2007
@@ -71,8 +71,10 @@
 
     // Statements for MainObject table
     protected String dropMainTable = "DROP TABLE NATIVE_MAIN_OBJECT";
+    protected String dropDerivedTable = "DROP TABLE NATIVE_DERIVED_OBJECT";
     protected String dropRefTable = "DROP TABLE NATIVE_REFERENCE_OBJECT";
     protected String insertDummyRowMainTable = "INSERT INTO NATIVE_MAIN_OBJECT (NAME) VALUES ('Dummy_1')";
+    protected String insertDummyRowDerivedTable = "INSERT INTO NATIVE_DERIVED_OBJECT (NAME) VALUES ('Dummy_1')";
     protected String insertDummyRowRefTable = "INSERT INTO NATIVE_REFERENCE_OBJECT (NAME) VALUES ('Dummy_2')";
 
     protected String addConstraintMainTableToRefTable = "ALTER TABLE NATIVE_MAIN_OBJECT ADD CONSTRAINT " +
@@ -80,6 +82,7 @@
 
     protected String dropConstraintMainTable;
     protected String createMainTable;
+    protected String createDerivedTable;
     protected String createRefTable;
 
     protected Platform platform;
@@ -102,10 +105,13 @@
             try{executeStatement(dropConstraintMainTable);}catch(Exception e){}
             try{executeStatement(dropRefTable);}catch(Exception e){}
             try{executeStatement(dropMainTable);}catch(Exception e){}
+            try{executeStatement(dropDerivedTable);}catch(Exception e){}
             executeStatement(createMainTable);
+            executeStatement(createDerivedTable);
             executeStatement(createRefTable);
             executeStatement(addConstraintMainTableToRefTable);
             executeStatement(insertDummyRowMainTable);
+            executeStatement(insertDummyRowDerivedTable);
             executeStatement(insertDummyRowRefTable);
         }
 
@@ -1128,6 +1134,7 @@
     public static class MainObject implements DatabaseIdentityTest.MainObjectIF
     {
         private Long identifier;
+        private String ojbConcreteClass;
         private String name;
         private List allReferences;
         // we use anonymous field for FK
@@ -1136,10 +1143,12 @@
 
         public MainObject()
         {
+            ojbConcreteClass = this.getClass().getName();
         }
 
         public MainObject(Long identifier, String name)
         {
+            this();
             this.identifier = identifier;
             this.name = name;
         }
@@ -1199,6 +1208,18 @@
                     .append("allReferences", (allReferences != null ? allReferences.toString() : "null"))
                     .append("singleReference", (singleReference != null ? singleReference.getClass().toString(): "null"))
                     .toString();
+        }
+    }
+
+    public static class DerivedObject extends MainObject
+    {
+        public DerivedObject()
+        {
+        }
+
+        public DerivedObject(Long identifier, String name)
+        {
+            super(identifier, name);
         }
     }
 

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository.xml
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository.xml?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository.xml Thu Mar  1 16:52:47 2007
@@ -50,6 +50,7 @@
 <!ENTITY junit_cloneable SYSTEM "repository_junit_cloneable.xml">
 <!ENTITY junit_inheritance SYSTEM "repository_junit_inheritance.xml">
 <!ENTITY junit_pathClass SYSTEM "repository_junit_pathClass.xml">
+<!ENTITY junit_pagination SYSTEM "repository_junit_pagination.xml">
 
 <!ENTITY user SYSTEM "repository_user.xml">
 <!ENTITY ejb SYSTEM "repository_ejb.xml">
@@ -62,14 +63,15 @@
     <!-- include all used database connections -->
     &database;
 
-    <!-- include ojb internal mappings here -->
+    <!-- include ojb internal mappings here, can be removed (with <!ENTITY entry)
+    if internal tables not used. See documentation platform-guide -->
     &internal;
 
     <!-- include user defined mappings here -->
     &user;
 
     <!-- include mappings for JUnit tests -->
-    <!-- This could be removed (with <!ENTITY entry),
+    <!-- This can be removed (with <!ENTITY entry),
          if junit test suite was not used
     -->
     &junit;
@@ -82,7 +84,9 @@
     &junit_cloneable;
     &junit_inheritance;
     &junit_pathClass;
+    &junit_pagination;
 
-    <!-- include mappings for the EJB-examples -->
+    <!-- include mappings for the EJB-examples, comment in before run
+     the ejb-example tests -->
     <!-- &ejb; -->
 </descriptor-repository>

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_database.xml
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_database.xml?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_database.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_database.xml Thu Mar  1 16:52:47 2007
@@ -49,6 +49,14 @@
      >
 
         <!--
+            If set 'true' OJB use the native database LIMIT and OFFSET syntax
+            for limit and paging queries (if it's supported by the database and OJB's Platform
+            implementation class). If set 'false' OJB simulate limit and paging by a specific
+            result set iterator (this can result in bad performance on big result sets).
+        -->
+        <attribute attribute-name="nativeLimitOffset" attribute-value="true" />
+
+        <!--
             On initialization of connections the ConnectionFactory change the 'autoCommit'
             state dependent of the used 'useAutoCommit' setting. This doesn't work in all
             situations/environments, thus for useAutoCommit="1" the ConnectionFactory does
@@ -170,6 +178,13 @@
             <!-- attribute attribute-name="seq.cycle" attribute-value="false"/ -->
             <!-- attribute attribute-name="seq.cache" attribute-value="20"/ -->
             <!-- attribute attribute-name="seq.order" attribute-value="false"/ -->
+
+            <!-- optional attributes supported by SequenceManagerIdentityImpl, more details
+            please see "Sequence Manager" guide or/and javadoc of classes for more information -->
+            <!-- If set 'true' OJB use the JDBC 3.0 method "Statement.getGeneratedKeys()"
+            to obtain generated database identity keys. If set 'false' OJB use a separate
+            database specific "last identity call" query to request the generated identity key. -->
+            <attribute attribute-name="seq.generatedKeys" attribute-value="true"/>
 
         </sequence-manager>
    </jdbc-connection-descriptor>

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_meta_seq.xml
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_meta_seq.xml?view=diff&rev=513565&r1=513564&r2=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_meta_seq.xml (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_meta_seq.xml Thu Mar  1 16:52:47 2007
@@ -518,6 +518,8 @@
       class="org.apache.ojb.broker.sequence.DatabaseIdentityTest$MainObject"
       table="NATIVE_MAIN_OBJECT"
     >
+        <extent-class class-ref="org.apache.ojb.broker.sequence.DatabaseIdentityTest$DerivedObject" />
+
         <field-descriptor
         name="identifier"
         column="NATIVE_ID"
@@ -525,6 +527,66 @@
         primarykey="true"
         autoincrement="true"
         access="readonly"
+        />
+
+        <field-descriptor
+        name="ojbConcreteClass"
+        column="CLASS_NAME"
+        jdbc-type="VARCHAR"
+        />
+
+        <field-descriptor
+        name="refFK"
+        column="REF_ID"
+        jdbc-type="BIGINT"
+        access="anonymous"
+        />
+
+        <field-descriptor
+        name="name"
+        column="NAME"
+        jdbc-type="VARCHAR"
+        />
+
+        <reference-descriptor
+        name="singleReference"
+        class-ref="org.apache.ojb.broker.sequence.DatabaseIdentityTest$SingleReference"
+        proxy="false"
+        auto-retrieve="true"
+        auto-update="none"
+        auto-delete="none">
+            <foreignkey field-ref="refFK"/>
+      </reference-descriptor>
+
+        <collection-descriptor
+         name="allReferences"
+         element-class-ref="org.apache.ojb.broker.sequence.DatabaseIdentityTest$CollectionReference"
+         auto-retrieve="true"
+         auto-update="none"
+         auto-delete="none"
+      >
+         <orderby name="refIdentifier" sort="DESC"/>
+         <inverse-foreignkey field-ref="fkIdentifier"/>
+      </collection-descriptor>
+    </class-descriptor>
+
+    <class-descriptor
+      class="org.apache.ojb.broker.sequence.DatabaseIdentityTest$DerivedObject"
+      table="NATIVE_DERIVED_OBJECT"
+    >
+        <field-descriptor
+        name="identifier"
+        column="NATIVE_ID"
+        jdbc-type="BIGINT"
+        primarykey="true"
+        autoincrement="true"
+        access="readonly"
+        />
+
+        <field-descriptor
+        name="ojbConcreteClass"
+        column="CLASS_NAME"
+        jdbc-type="VARCHAR"
         />
 
         <field-descriptor

Added: db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_pagination.xml
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_pagination.xml?view=auto&rev=513565
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_pagination.xml (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_pagination.xml Thu Mar  1 16:52:47 2007
@@ -0,0 +1,262 @@
+
+<!-- =================================================== -->
+<!--     Mapping for ImageContainerTest                  -->
+<!-- =================================================== -->
+<class-descriptor
+    class="org.apache.ojb.broker.PaginationTest$Book"
+    table="PAGE_BOOK"
+    >
+    <field-descriptor
+        name="id"
+        column="ID_"
+        jdbc-type="INTEGER"
+        primarykey="true"
+        autoincrement="true"
+        />
+
+    <field-descriptor
+        name="title"
+        column="TITLE_"
+        jdbc-type="VARCHAR"
+        />
+
+    <field-descriptor
+        name="publicationDate"
+        column="DATE_"
+        jdbc-type="TIMESTAMP"
+        conversion="org.apache.ojb.broker.accesslayer.conversions.JavaDate2SqlTimestampFieldConversion"
+        />
+
+    <field-descriptor
+        name="cover"
+        column="COVER_"
+        jdbc-type="LONGVARBINARY"
+        />
+
+    <field-descriptor
+        name="version"
+        column="VERSION_"
+        jdbc-type="INTEGER"
+        locking="true"
+        />
+
+    <field-descriptor
+        name="fkPublisher"
+        column="FK_PUBLISHER"
+        jdbc-type="INTEGER"
+        field-class="org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDirectImpl"
+        />
+
+    <reference-descriptor name="publisher"
+        class-ref="org.apache.ojb.broker.PaginationTest$Publisher"
+        proxy="true"
+        auto-retrieve="true"
+        auto-update="object"
+        auto-delete="object"
+        >
+        <foreignkey field-ref="fkPublisher"/>
+    </reference-descriptor>
+
+    <collection-descriptor
+        name="reviews"
+        element-class-ref="org.apache.ojb.broker.PaginationTest$Review"
+        proxy="true"
+        auto-retrieve="true"
+        auto-update="object"
+        auto-delete="object"
+        >
+        <orderby name="fkBook" sort="ASC"/>
+        <inverse-foreignkey field-ref="fkBook"/>
+    </collection-descriptor>
+
+    <collection-descriptor
+        name="authors"
+        collection-class="org.apache.ojb.broker.util.collections.ManageableArrayList"
+        element-class-ref="org.apache.ojb.broker.PaginationTest$Author"
+        indirection-table="PAGE_PUBLICATION"
+        proxy="true"
+        auto-retrieve="true"
+        auto-update="object"
+        auto-delete="object"
+        >
+        <fk-pointing-to-this-class column="BOOK_ID"/>
+        <fk-pointing-to-element-class column="AUTHOR_ID"/>
+    </collection-descriptor>
+</class-descriptor>
+
+<class-descriptor class="org.apache.ojb.broker.PaginationTest$Publisher">
+    <extent-class class-ref="org.apache.ojb.broker.PaginationTest$PublisherImpl"/>
+</class-descriptor>
+
+<class-descriptor
+    class="org.apache.ojb.broker.PaginationTest$PublisherImpl"
+    table="PAGE_PUBLISHER"
+    >
+    <field-descriptor
+        name="id"
+        column="ID_"
+        jdbc-type="INTEGER"
+        primarykey="true"
+        autoincrement="true"
+        />
+
+    <field-descriptor
+        name="name"
+        column="NAME_"
+        jdbc-type="VARCHAR"
+        />
+
+    <field-descriptor
+        name="version"
+        column="VERSION_"
+        jdbc-type="INTEGER"
+        locking="true"
+        />
+
+    <collection-descriptor
+        name="authors"
+        element-class-ref="org.apache.ojb.broker.PaginationTest$Author"
+        proxy="true"
+        auto-retrieve="true"
+        auto-update="object"
+        auto-delete="object"
+        >
+        <inverse-foreignkey field-ref="fkPublisher"/>
+    </collection-descriptor>
+
+    <collection-descriptor
+        name="books"
+        element-class-ref="org.apache.ojb.broker.PaginationTest$Book"
+        proxy="true"
+        auto-retrieve="true"
+        auto-update="object"
+        auto-delete="object"
+        >
+        <inverse-foreignkey field-ref="fkPublisher"/>
+    </collection-descriptor>
+
+</class-descriptor>
+
+<class-descriptor
+    class="org.apache.ojb.broker.PaginationTest$Author"
+    table="PAGE_AUTHOR"
+    >
+    <field-descriptor
+        name="id"
+        column="ID_"
+        jdbc-type="INTEGER"
+        primarykey="true"
+        autoincrement="true"
+        />
+
+    <field-descriptor
+        name="name"
+        column="NAME_"
+        jdbc-type="VARCHAR"
+        />
+
+    <field-descriptor
+        name="version"
+        column="VERSION_"
+        jdbc-type="INTEGER"
+        locking="true"
+        />
+
+    <field-descriptor
+        name="fkPublisher"
+        column="FK_PUBLISHER"
+        jdbc-type="INTEGER"
+        field-class="org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDirectImpl"
+    />
+
+    <reference-descriptor name="publisher"
+        class-ref="org.apache.ojb.broker.PaginationTest$Publisher"
+        proxy="true"
+        auto-retrieve="true"
+        auto-update="object"
+        auto-delete="object"
+        >
+        <foreignkey field-ref="fkPublisher"/>
+    </reference-descriptor>
+
+    <collection-descriptor
+        name="books"
+        collection-class="org.apache.ojb.broker.util.collections.ManageableArrayList"
+        element-class-ref="org.apache.ojb.broker.PaginationTest$Book"
+        indirection-table="PAGE_PUBLICATION"
+        proxy="true"
+        auto-retrieve="true"
+        auto-update="object"
+        auto-delete="object"
+        >
+        <fk-pointing-to-this-class column="AUTHOR_ID"/>
+        <fk-pointing-to-element-class column="BOOK_ID"/>
+    </collection-descriptor>
+
+</class-descriptor>
+
+<class-descriptor
+    class="org.apache.ojb.broker.PaginationTest$Review"
+    table="PAGE_REVIEW"
+    >
+    <field-descriptor
+        name="id"
+        column="ID_"
+        jdbc-type="INTEGER"
+        primarykey="true"
+        autoincrement="true"
+        />
+
+    <field-descriptor
+        name="vote"
+        column="VOTE_"
+        jdbc-type="INTEGER"
+        />
+
+    <field-descriptor
+        name="summary"
+        column="SUMMARY_"
+        jdbc-type="VARCHAR"
+        />
+
+    <field-descriptor
+        name="version"
+        column="VERSION_"
+        jdbc-type="INTEGER"
+        locking="true"
+        />
+
+    <field-descriptor
+        name="fkAuthor"
+        column="FK_AUTHOR"
+        jdbc-type="INTEGER"
+        access="anonymous"
+        />
+
+    <field-descriptor
+        name="fkBook"
+        column="FK_BOOK"
+        jdbc-type="INTEGER"
+        />
+
+    <reference-descriptor name="author"
+        class-ref="org.apache.ojb.broker.PaginationTest$Author"
+        proxy="true"
+        auto-retrieve="true"
+        auto-update="object"
+        auto-delete="object"
+        >
+        <foreignkey field-ref="fkAuthor"/>
+    </reference-descriptor>
+
+    <reference-descriptor name="book"
+        class-ref="org.apache.ojb.broker.PaginationTest$Book"
+        proxy="true"
+        auto-retrieve="true"
+        auto-update="object"
+        auto-delete="object"
+        >
+        <foreignkey field-ref="fkBook"/>
+    </reference-descriptor>
+
+</class-descriptor>
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message