package org.apache.ojb.odmg;
/* Copyright 2002-2005 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.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Iterator;
import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.ojb.broker.Identity;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.QueryFactory;
import org.apache.ojb.broker.core.proxy.CollectionProxy;
import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl;
import org.apache.ojb.broker.core.proxy.CollectionProxyListener;
import org.apache.ojb.broker.core.proxy.IndirectionHandler;
import org.apache.ojb.broker.core.proxy.MaterializationListener;
import org.apache.ojb.broker.core.proxy.ProxyHelper;
import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
import org.apache.ojb.junit.ODMGTestCase;
import org.odmg.OQLQuery;
import org.odmg.Transaction;
/**
* Check the quality of object image comparison:
* - new referenced objects
* - deleted referenced objects
* - deleted referenced objects
* ...etc.
*
* Test cases for refactored odmg-api implementation. These tests asserts previously outstanding
* ODMG-issues and proxy object handling in the ODMG API.
*
* @author <a href="mailto:arminw@apache.org">Armin Waibel</a>
* @version $Id: ObjectImageTest.java,v 1.1.2.8 2005/12/13 18:18:25 arminw Exp $
*/
public class ObjectImageTest extends ODMGTestCase
{
static final int NONE = ObjectReferenceDescriptor.CASCADE_NONE;
static final int LINK = ObjectReferenceDescriptor.CASCADE_LINK;
static final int OBJECT = ObjectReferenceDescriptor.CASCADE_OBJECT;
static final String EOL = SystemUtils.LINE_SEPARATOR;
public static void main(String[] args)
{
junit.textui.TestRunner.main(new String[]{ObjectImageTest.class.getName()});
}
public void testReplaceOneToOneReference() throws Exception
{
String prefix = "testReplaceOneToOneReference_" + System.currentTimeMillis();
ojbChangeReferenceSetting(Book.class, "reviews", true, NONE, NONE, false);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
Book book = new Book(prefix, null, null);
Publisher p_1 = new PublisherImpl(prefix);
Publisher p_2 = new PublisherImpl(prefix + "_replaced");
book.setPublisher(p_1);
database.makePersistent(book);
database.makePersistent(p_1);
database.makePersistent(p_2);
tx.commit();
Integer book_version = book.getVersion();
Integer p1_version = p_1.getVersion();
Integer p2_version = p_2.getVersion();
tx.begin();
tx.lock(book, Transaction.WRITE);
tx.lock(book.getPublisher(), Transaction.READ);
tx.lock(p_2, Transaction.READ);
book.setPublisher(p_2);
tx.commit();
assertEquals(book_version.intValue() + 1, book.getVersion().intValue());
assertEquals(p1_version, p_1.getVersion());
assertEquals(p2_version, p_2.getVersion());
}
public void testAddCollectionObjectToExistingObject() throws Exception
{
String prefix = "testAddCollectionObjectToExistingObject_" + System.currentTimeMillis();
ojbChangeReferenceSetting(Book.class, "reviews", true, NONE, NONE, false);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
Book book = new Book(prefix, null, null);
Review r1 = new Review(prefix + "_1");
database.makePersistent(book);
database.makePersistent(r1);
tx.commit();
Integer book_version = book.getVersion();
Integer r_1_version = r1.getVersion();
Review r2 = new Review(prefix + "_2");
tx.begin();
tx.lock(r1, Transaction.WRITE);
tx.lock(book, Transaction.READ);
book.addReview(r1);
book.addReview(r2);
database.makePersistent(r2);
tx.commit();
assertEquals(book_version, book.getVersion());
assertTrue(book.getId() != null);
Integer r_2_version = r2.getVersion();
tx.begin();
tx.getBroker().clearCache();
Book loadedCopy = (Book) tx.getBroker().getObjectByIdentity(
tx.getBroker().serviceIdentity().buildIdentity(Book.class, book.getId()));
assertNotNull(loadedCopy);
assertNotNull(loadedCopy.getReviews());
assertEquals(2, loadedCopy.getReviews().size());
assertEquals(book_version, loadedCopy.getVersion());
Review new_r1 = (Review) loadedCopy.getReviews().get(0);
Review new_r2 = (Review) loadedCopy.getReviews().get(1);
assertEquals(r_1_version.intValue() + 1, new_r1.getVersion().intValue());
assertEquals(r_2_version, new_r2.getVersion());
tx.getBroker().clearCache();
Criteria criteria = new Criteria();
criteria.addLike("title", prefix);
Query q = QueryFactory.newQuery(Book.class, criteria);
Collection books = tx.getBroker().getCollectionByQuery(q);
assertNotNull(books);
assertEquals(1, books.size());
Book new_book = (Book) books.iterator().next();
tx.commit();
assertEquals(book_version, new_book.getVersion());
tx.begin();
tx.lock(loadedCopy, Transaction.WRITE);
Review removed = (Review) loadedCopy.getReviews().remove(0);
Review stayed = (Review) loadedCopy.getReviews().get(0);
tx.commit();
// expect same version, nothing should be changed
assertEquals(r_2_version, stayed.getVersion());
//
//assertEquals(r_1_version, removed.getVersion());
tx.begin();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(prefix);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
tx.commit();
assertEquals(1, b.getReviews().size());
Review r = (Review) b.getReviews().get(0);
if(!r.equals(r1) && !r.equals(r2))
{
fail("Wrong object or wrong object version returned. Returned obj was "
+ EOL + r + " expected object was " + EOL + r1 + " or " + EOL + r2);
}
}
/**
* test persistence by reachability of collection reference objects
*/
public void testPersistenceByReachability_1() throws Exception
{
String name = "testPersistenceByReachability_1_" + System.currentTimeMillis();
ojbChangeReferenceSetting(Book.class, "reviews", true, NONE, NONE, true);
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
Review r2 = new Review(name);
Review r3 = new Review(name + "_not_persistent");
ArrayList reviews = new ArrayList();
reviews.add(r1);
reviews.add(r2);
reviews.add(r3);
book.setReviews(reviews);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
Review r4 = new Review(name + "_new_added");
// add a new review after make persistent main object
book.addReview(r4);
tx.setCascadingDelete(Book.class, true);
// remove object after make persistent main object
book.removeReview(r3);
tx.commit();
// System.err.println("## Insert main object with 3 referecnes");
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertNotNull(b.getReviews());
assertEquals(3, b.getReviews().size());
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name + "_new_added");
result = (Collection) query.execute();
// we expect the delayed added Review object
assertEquals(1, result.size());
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name + "_not_persistent");
result = (Collection) query.execute();
// we expect the removed Review object wasn't persistet
assertEquals(0, result.size());
tx.commit();
}
/**
* test persistence by reachability of collection reference objects
*/
public void testPersistenceByReachability_2() throws Exception
{
String name = "testPersistenceByReachability_2_" + System.currentTimeMillis();
ojbChangeReferenceSetting(Book.class, "reviews", true, NONE, NONE, true);
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
Review r2 = new Review(name);
Review r3 = new Review(name + "_not_persistent");
ArrayList reviews = new ArrayList();
reviews.add(r1);
reviews.add(r2);
reviews.add(r3);
book.setReviews(reviews);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
Review r4 = new Review(name + "_new_added");
// add a new review after make persistent main object
book.addReview(r4);
tx.setCascadingDelete(Book.class, true);
// remove object after make persistent main object
book.removeReview(r3);
tx.checkpoint();
//tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertNotNull(b.getReviews());
assertEquals(3, b.getReviews().size());
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name + "_new_added%");
result = (Collection) query.execute();
// we expect the delayed added Review object
assertEquals(1, result.size());
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name + "_not_persistent");
result = (Collection) query.execute();
// we expect the removed Review object wasn't persistet
assertEquals(0, result.size());
b.setTitle(name + "_updated");
tx.commit();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name + "_updated");
result = (Collection) query.execute();
assertEquals(1, result.size());
Book b_updated = (Book) result.iterator().next();
assertNotNull(b_updated.getReviews());
assertEquals(3, b_updated.getReviews().size());
assertEquals(name+"_updated", b_updated.getTitle());
}
public void testAddPersistentObjectTo1toN() throws Exception
{
String name = "testAddPersistentObjectTo1toN_" + System.currentTimeMillis();
Review review = new Review(name);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(review);
tx.commit();
Integer versionReview = review.getVersion();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
tx = (TransactionExt) odmg.newTransaction();
tx.begin();
// tx.lock(review, Transaction.WRITE);
database.makePersistent(book);
book.addReview(review);
tx.commit();
// the Review object has to be linked
assertEquals("expect that this object was updated", versionReview.intValue() + 1, review.getVersion().intValue());
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertNotNull(b.getReviews());
assertEquals(1, b.getReviews().size());
tx.commit();
}
public void testAddPersistentObjectToMtoN() throws Exception
{
String name = "testAddPersistentObjectToMtoN_" + System.currentTimeMillis();
Author author = new Author(name, null);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(author);
tx.commit();
Integer versionReview = author.getVersion();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
book.addAuthor(author);
author.addBook(book);
tx.commit();
// the Review object has to be linked
assertEquals("expect that this object wasn't updated", versionReview.intValue(), author.getVersion().intValue());
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertNotNull(b.getAuthors());
assertEquals(1, b.getAuthors().size());
tx.commit();
}
/**
* only lock object, no changes made
*/
public void testChangeMainFields() throws Exception
{
String name = "testChangeMainFields_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer version = book.getVersion();
// System.err.println("### 1. commit, insert new object");
tx.begin();
tx.lock(book, Transaction.WRITE);
tx.commit();
// System.err.println("### 2. commit, no changes");
assertEquals(version, book.getVersion());
tx.begin();
tx.lock(book, Transaction.WRITE);
// we set the same date, so no reason to update
book.setPublicationDate(new Date(date.getTime()));
tx.commit();
// System.err.println("### 3. commit, replace with same date");
assertEquals(version, book.getVersion());
tx.begin();
tx.lock(book, Transaction.WRITE);
// now we change the date
Date d = new Date(1111);
book.setPublicationDate(d);
tx.commit();
// System.err.println("### 4. commit, changed date");
assertFalse(date.equals(book.getPublicationDate()));
assertFalse(version.equals(book.getVersion()));
}
/**
* modify field of main object
*/
public void testChangeMainFields_2() throws Exception
{
String name = "testChangeMainFields_2_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer version = book.getVersion();
tx.begin();
tx.lock(book, Transaction.WRITE);
book.setCover(new byte[]{2,3,4,5,6,7,8,8});
tx.commit();
assertFalse(version.equals(book.getVersion()));
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertFalse(version.equals(b.getVersion()));
tx.commit();
}
/**
* lock object and lock serialized unmodified version again
*/
public void testChangeMainFields_3() throws Exception
{
String name = "testChangeMainFields_3_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer version = book.getVersion();
tx.begin();
tx.lock(book, Transaction.WRITE);
book = (Book) SerializationUtils.clone(book);
tx.lock(book, Transaction.WRITE);
tx.commit();
assertEquals(version, book.getVersion());
}
/**
* Double lock object with reference
*/
public void testChangeOneToOneReference_1() throws Exception
{
String name = "testChangeOneToOneReference_1_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("### 1. commit, insert new object");
Integer versionBook = book.getVersion();
Integer versionPublisher = book.getPublisher().getVersion();
tx.begin();
tx.lock(book, Transaction.WRITE);
tx.lock(book, Transaction.WRITE);
tx.commit();
// System.err.println("### 2. commit, double lock call, no changes");
assertEquals(versionBook, book.getVersion());
assertEquals(versionPublisher, book.getVersion());
}
/**
* Double lock object with reference and proxy reference
*/
public void testChangeOneToOneReference_1b() throws Exception
{
String name = "testChangeOneToOneReference_1b_" + System.currentTimeMillis();
ojbChangeReferenceSetting(Book.class, "publisher", true, NONE, NONE, true);
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("### 1. commit, insert new object");
Integer versionBook = book.getVersion();
Integer versionPublisher = book.getPublisher().getVersion();
tx.begin();
tx.lock(book, Transaction.WRITE);
tx.lock(book, Transaction.WRITE);
tx.commit();
// System.err.println("### 2. commit, double lock call, no changes");
assertEquals(versionBook, book.getVersion());
assertEquals(versionPublisher, book.getVersion());
}
/**
* lock object with reference and lock serialized version again
*/
public void testChangeOneToOneReference_2() throws Exception
{
String name = "testChangeOneToOneReference_2_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("### 1. commit, insert new object");
Integer versionBook = book.getVersion();
Integer versionPublisher = book.getPublisher().getVersion();
tx.begin();
tx.lock(book, Transaction.WRITE);
// nothing changed, so no need to update objects
book = (Book) SerializationUtils.clone(book);
tx.lock(book, Transaction.WRITE);
tx.commit();
assertEquals(versionBook, book.getVersion());
assertEquals(versionPublisher, book.getVersion());
}
/**
* lock object with reference, change reference only
*/
public void testChangeOneToOneReference_3() throws Exception
{
String name = "testChangeOneToOneReference_2_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("### 1. commit, insert new object");
Integer versionBook = book.getVersion();
Integer versionPublisher = book.getPublisher().getVersion();
tx.begin();
tx.lock(book, Transaction.WRITE);
// nothing changed, so no need to update objects
book = (Book) SerializationUtils.clone(book);
Publisher p = book.getPublisher();
p.setName(name + "_updated");
// not needed to re-lock, because nothing changed, but
// if we lock Book no update should be done, because nothing changed
tx.lock(book, Transaction.WRITE);
// we have to re-lock the changed objects, because it was serialized
tx.lock(p, Transaction.WRITE);
tx.commit();
// no changes made in Book
assertEquals(versionBook, book.getVersion());
// publisher should be updated
assertEquals(new Integer(versionPublisher.intValue() + 1), p.getVersion());
}
/**
* lock object with reference, replace reference only
*/
public void testReplaceOneToOneReference_1() throws Exception
{
String name = "testChangeOneToOneReference_2_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("### 1. commit, insert new object");
Integer versionBook = book.getVersion();
Integer versionPublisher = book.getPublisher().getVersion();
tx.begin();
tx.lock(book, Transaction.WRITE);
Publisher p = new PublisherImpl(name + "_new");
// set new Publisher instance
book.setPublisher(p);
tx.lock(p, Transaction.WRITE);
tx.commit();
// changes made in Book
assertEquals(new Integer(versionBook.intValue() + 1), book.getVersion());
// publisher should not be updated, because it was replaced
assertEquals(versionPublisher, p.getVersion());
}
/**
* lock object with reference, replace reference only
*/
public void testReplaceOneToOneReference_2() throws Exception
{
String name = "testChangeOneToOneReference_2_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("### 1. commit, insert new object");
Integer versionBook = book.getVersion();
Integer versionPublisher = book.getPublisher().getVersion();
tx.begin();
tx.lock(book, Transaction.WRITE);
book = (Book) SerializationUtils.clone(book);
Publisher p = new PublisherImpl(name + "_new");
// set new Publisher instance
book.setPublisher(p);
// not needed to re-lock, because nothing changed, but
// if we lock Book no update should be done, because nothing changed
tx.lock(book, Transaction.WRITE);
// we have to re-lock the changed objects, because it was serialized
tx.lock(p, Transaction.WRITE);
tx.commit();
// changes made in Book
assertEquals(new Integer(versionBook.intValue() + 1), book.getVersion());
// publisher should not be updated, because it was replaced
assertEquals(versionPublisher, p.getVersion());
}
/**
* check materialization of proxy object
*/
public void testChangeOneToOneReference_4() throws Exception
{
ojbChangeReferenceSetting(Book.class, "publisher", true, NONE, NONE, true);
String name = "testChangeOneToOneReference_4_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
IndirectionHandler handler = ProxyHelper.getIndirectionHandler(b.getPublisher());
assertNotNull(handler);
assertFalse(handler.alreadyMaterialized());
handler.addListener(
new MaterializationListener()
{
public void beforeMaterialization(IndirectionHandler handler, Identity oid)
{
fail("Reference shall not materialize while locking");
}
public void afterMaterialization(IndirectionHandler handler, Object materializedObject)
{
}
}
);
tx.lock(b, Transaction.WRITE);
tx.commit();
assertEquals(versionBook, b.getVersion());
}
/**
* replace proxy reference by new reference object
*/
public void testChangeOneToOneReference_5() throws Exception
{
ojbChangeReferenceSetting(Book.class, "publisher", true, NONE, NONE, true);
String name = "testChangeOneToOneReference_5_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("### 1. commit, insert new object");
Integer versionBook = book.getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
IndirectionHandler handler = ProxyHelper.getIndirectionHandler(b.getPublisher());
assertNotNull(handler);
assertFalse(handler.alreadyMaterialized());
handler.addListener(
new MaterializationListener()
{
public void beforeMaterialization(IndirectionHandler handler, Identity oid)
{
fail("Reference shall not materialize while locking");
}
public void afterMaterialization(IndirectionHandler handler, Object materializedObject)
{
}
}
);
// no need to lock with default settings, because lock is done when query object
tx.lock(b, Transaction.WRITE);
// replace 1:1 reference
Publisher p = new PublisherImpl(name+"_new");
b.setPublisher(p);
//tx.lock(p, Transaction.WRITE);
tx.commit();
// we expect increased version, because Book object needs update - changed FK
assertEquals(new Integer(versionBook.intValue() + 1), b.getVersion());
// should should differ, because new reference should be stored
assertFalse(publisher.getName().equals(p.getName()));
assertNotNull(p.getVersion());
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
assertEquals(1, result.size());
b = (Book) result.iterator().next();
Publisher newP = b.getPublisher();
assertNotNull(newP);
assertEquals(name+"_new", newP.getName());
}
/**
* update referenced object
*/
public void testChangeOneToOneReference_6() throws Exception
{
String name = "testChangeOneToOneReference_6_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
Integer versionPublisher = book.getPublisher().getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
tx.lock(b, Transaction.WRITE);
b.getPublisher().setName("updated_" + b.getPublisher().getName());
tx.commit();
// nothing changed
assertEquals(versionBook, b.getVersion());
// version should should differ, because reference should be updated
assertFalse(versionPublisher.equals(b.getPublisher().getVersion()));
assertEquals("updated_" + name, b.getPublisher().getName());
}
/**
* add new reference
*/
public void testChangeOneToOneReference_7() throws Exception
{
String name = "testChangeOneToOneReference_7_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
tx.lock(b, Transaction.WRITE);
assertNull(b.getPublisher());
Publisher publisher = new PublisherImpl(name);
b.setPublisher(publisher);
// tx.lock(publisher, Transaction.WRITE);
tx.commit();
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
assertEquals(1, result.size());
b = (Book) result.iterator().next();
tx.commit();
// we expect increased version, because Book object needs update
assertEquals(new Integer(versionBook.intValue() + 1), b.getVersion());
// version should differ from null, because new reference should be stored
assertNotNull(b.getPublisher());
assertNotNull(b.getPublisher().getVersion());
assertEquals(name, b.getPublisher().getName());
}
/**
* remove reference
*/
public void testChangeOneToOneReference_8() throws Exception
{
String name = "testChangeOneToOneReference_8_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
Integer versionPublisher = book.getPublisher().getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
tx.lock(b, Transaction.WRITE);
b.setPublisher(null);
tx.commit();
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
assertEquals(1, result.size());
b = (Book) result.iterator().next();
tx.commit();
// we expect increased version, because Book object needs update
assertEquals(new Integer(versionBook.intValue() + 1), b.getVersion());
assertNull(b.getPublisher());
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select publishers from " + Publisher.class.getName() + " where name like $1");
query.bind(name);
result = (Collection) query.execute();
// we don't remove the reference object
assertEquals(1, result.size());
Publisher p = (Publisher) result.iterator().next();
assertEquals(name, p.getName());
// removed 1:1 reference, expect unchanged version
assertEquals(versionPublisher, p.getVersion());
tx.commit();
}
/**
* delete reference
*/
public void testChangeOneToOneReference_8b() throws Exception
{
String name = "testChangeOneToOneReference_8b_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Publisher publisher = new PublisherImpl(name);
book.setPublisher(publisher);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
tx.lock(b, Transaction.WRITE);
database.deletePersistent(b.getPublisher());
b.setPublisher(null);
tx.commit();
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
assertEquals(1, result.size());
b = (Book) result.iterator().next();
tx.commit();
// we expect increased version, because Book object needs update
assertEquals(new Integer(versionBook.intValue() + 1), b.getVersion());
assertNull(b.getPublisher());
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select publishers from " + Publisher.class.getName() + " where name like $1");
query.bind(name);
result = (Collection) query.execute();
// we don't remove the reference object
assertEquals(0, result.size());
tx.commit();
}
/**
* check materialzation of collection reference
*/
public void testCollectionReference_1() throws Exception
{
String name = "testCollectionReference_1_" + System.currentTimeMillis();
ojbChangeReferenceSetting(Book.class, "reviews", true, NONE, NONE, true);
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
Review r2 = new Review(name);
Review r3 = new Review(name);
ArrayList reviews = new ArrayList();
reviews.add(r1);
reviews.add(r2);
reviews.add(r3);
book.setReviews(reviews);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("## Insert main object with 3 referecnes");
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
CollectionProxy handler = ProxyHelper.getCollectionProxy(b.getReviews());
assertFalse("Don't expect an materialized collection proxy", handler.isLoaded());
handler.addListener(new CollectionProxyListener()
{
public void beforeLoading(CollectionProxyDefaultImpl colProxy)
{
fail("Collection proxy shouldn't be materialized");
}
public void afterLoading(CollectionProxyDefaultImpl colProxy)
{
}
});
assertNotNull(b.getReviews());
assertEquals(3, b.getReviews().size());
tx.lock(b, Transaction.WRITE);
tx.commit();
}
/**
* update collection reference object
*/
public void testCollectionReference_2a() throws Exception
{
String name = "testCollectionReference_2a_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
Review r2 = new Review(name);
Review r3 = new Review(name);
ArrayList reviews = new ArrayList();
reviews.add(r1);
reviews.add(r2);
reviews.add(r3);
book.setReviews(reviews);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("## Insert main object with 3 referecnes");
Integer versionBook = book.getVersion();
Integer versionR1 = ((Review) book.getReviews().get(0)).getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
assertNotNull(b.getReviews());
assertEquals(3, b.getReviews().size());
tx.lock(b, Transaction.WRITE);
Review newR2 = (Review) b.getReviews().get(1);
newR2.setSummary("updated" + name);
final int newR2id = newR2.getId().intValue();
tx.commit();
assertEquals(versionBook, b.getVersion());
// this referenced object was not updated
Integer versionR1New = ((Review) b.getReviews().get(0)).getVersion();
assertEquals(versionR1, versionR1New);
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
assertEquals(1, result.size());
b = (Book) result.iterator().next();
assertNotNull(b.getReviews());
assertEquals(3, b.getReviews().size());
// Search for the updated R2:
final List updatedReviews = b.getReviews();
for (int i = 0; i < updatedReviews.size(); i++)
{
newR2 = (Review) updatedReviews.get(i);
if (newR2id == newR2.getId().intValue()) {
break;
}
}
assertEquals("Could not find the updated review in the returned results",
newR2id, newR2.getId().intValue());
assertEquals("updated" + name, newR2.getSummary());
assertEquals(versionBook, b.getVersion());
// this referenced object was not updated
versionR1New = ((Review) b.getReviews().get(0)).getVersion();
assertEquals(versionR1, versionR1New);
}
/**
* update proxy collection reference object
*/
public void testCollectionReference_2b() throws Exception
{
String name = "testCollectionReference_2b_" + System.currentTimeMillis();
ojbChangeReferenceSetting(Book.class, "reviews", true, NONE, NONE, true);
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
Review r2 = new Review(name);
Review r3 = new Review(name);
ArrayList reviews = new ArrayList();
reviews.add(r1);
reviews.add(r2);
reviews.add(r3);
book.setReviews(reviews);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
// System.err.println("## Insert main object with 3 referecnes");
Integer versionBook = book.getVersion();
Integer versionR0 = ((Review) book.getReviews().get(0)).getVersion();
Integer versionR1 = ((Review) book.getReviews().get(1)).getVersion();
tx.begin();
tx.getBroker().clearCache();
// System.err.println("## Started new tx");
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
assertNotNull(b.getReviews());
assertEquals(3, b.getReviews().size());
assertEquals(versionR0, ((Review) b.getReviews().get(0)).getVersion());
assertEquals(versionR1, ((Review) b.getReviews().get(1)).getVersion());
// System.err.println("## Query done");
tx.lock(b, Transaction.WRITE);
// System.err.println("## Lock object again");
Review newR1 = (Review) b.getReviews().get(1);
newR1.setSummary("updated" + name);
// System.err.println("## Before commit");
tx.commit();
// System.err.println("## Commit Book with updated Review");
assertEquals(versionBook, b.getVersion());
assertEquals(3, b.getReviews().size());
// the updated one
Integer versionR1New = ((Review) b.getReviews().get(1)).getVersion();
assertEquals(new Integer(versionR1.intValue() + 1), versionR1New);
// this referenced object was not updated
Integer versionR0New = ((Review) b.getReviews().get(0)).getVersion();
assertEquals(versionR0, versionR0New);
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
assertEquals(1, result.size());
b = (Book) result.iterator().next();
assertNotNull(b.getReviews());
assertEquals(3, b.getReviews().size());
tx.commit();
// query for updated Review
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind("updated" + name);
result = (Collection) query.execute();
tx.commit();
// the update Review object
assertEquals(1, result.size());
// query for unchanged Review objects
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
assertEquals(2, result.size());
assertEquals(versionR0, ((Review) new ArrayList(result).get(0)).getVersion());
}
/**
* remove collection reference object
* this test expects that removed 1:n referenced objects only
* be "unlinked" instead of deleted.
*/
public void testCollectionReference_3() throws Exception
{
String name = "testCollectionReference_3_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
ArrayList reviews = new ArrayList();
reviews.add(r1);
book.setReviews(reviews);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
Integer versionR1 = ((Review) book.getReviews().get(0)).getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
assertNotNull(b.getReviews());
assertEquals(1, b.getReviews().size());
//***********************************
tx.lock(b, Transaction.WRITE);
// remove from collection, but do not explicit delete
tx.setCascadingDelete(Book.class, "reviews", false);
Review newR1 = (Review) b.getReviews().remove(0);
tx.commit();
//***********************************
// only the removed reference has changed
assertEquals(versionBook, b.getVersion());
// expect an "unlinked" new version
assertEquals(new Integer(versionR1.intValue() + 1), newR1.getVersion());
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
// we don't delete the Review object, only remove from reference collection
assertEquals(1, result.size());
Review r = (Review) result.iterator().next();
// expect new object version, because the FK to main object was set null
assertEquals(new Integer(versionR1.intValue() + 1), r.getVersion());
tx.begin();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
assertEquals(1, result.size());
b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
// we have removed the Review object
assertEquals(0, b.getReviews().size());
}
/**
* remove collection reference object and explicit delete it
*/
public void testCollectionReference_3b() throws Exception
{
String name = "testCollectionReference_3b_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
ArrayList reviews = new ArrayList();
reviews.add(r1);
book.setReviews(reviews);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
assertNotNull(b.getReviews());
assertEquals(1, b.getReviews().size());
tx.lock(b, Transaction.WRITE);
// remove from collection and delete
Review newR1 = (Review) b.getReviews().remove(0);
database.deletePersistent(newR1);
tx.commit();
// only the removed reference has changed
assertEquals(versionBook, b.getVersion());
tx.begin();
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
assertEquals(0, result.size());
tx.begin();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
assertEquals(1, result.size());
b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
assertEquals(0, b.getReviews().size());
}
/**
* remove collection reference object with enabled auto-delete
*/
public void testCollectionReference_3c() throws Exception
{
String name = "testCollectionReference_3c_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
ArrayList reviews = new ArrayList();
reviews.add(r1);
book.setReviews(reviews);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
assertNotNull(b.getReviews());
assertEquals(1, b.getReviews().size());
tx.lock(b, Transaction.WRITE);
tx.setCascadingDelete(Book.class, "reviews", true);
// remove from collection with cascading delete
b.getReviews().remove(0);
tx.commit();
// only the removed reference has changed
assertEquals(versionBook, b.getVersion());
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
// cascading delete was used, so we don't expect an unlinked
// version of the Review class
assertEquals(0, result.size());
tx.begin();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
assertEquals(1, result.size());
b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
// we have removed the Review object
assertEquals(0, b.getReviews().size());
}
/**
* delete Book object with existing references
*/
public void testCollectionReference_4a() throws Exception
{
String name = "testCollectionReference_4_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
Review r2 = new Review(name);
Review r3 = new Review(name);
Author a1 = new Author(name, null);
Author a2 = new Author(name, null);
r1.setAuthor(a1);
r2.setAuthor(a1);
r3.setAuthor(a2);
ArrayList reviews = new ArrayList();
reviews.add(r1);
reviews.add(r2);
reviews.add(r3);
book.setReviews(reviews);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
assertNotNull(b.getReviews());
assertEquals(3, b.getReviews().size());
assertNotNull(((Review) b.getReviews().get(0)).getAuthor());
assertNotNull(((Review) b.getReviews().get(1)).getAuthor());
assertNotNull(((Review) b.getReviews().get(2)).getAuthor());
// Book instance should be already locked
// now mark Book for delete and disable cascading delete
// for the 1:n relation to Review class
tx.setCascadingDelete(Book.class, "reviews", false);
database.deletePersistent(b);
tx.commit();
// System.out.println("## After commit");
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
// we auto-delete the Review object, only remove from reference collection
assertEquals(3, result.size());
List list = new ArrayList(result);
assertNotNull(((Review) list.get(0)).getAuthor());
assertNotNull(((Review) list.get(1)).getAuthor());
assertNotNull(((Review) list.get(2)).getAuthor());
Review newR1 = (Review) list.get(0);
// book was deleted so we expect unlink of FK
assertNull(newR1.getFkBook());
tx.begin();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
assertEquals(0, result.size());
}
/**
* delete Book object with existing references and circular referencing objects
*/
public void testCollectionReference_4b() throws Exception
{
String name = "testCollectionReference_4_" + System.currentTimeMillis();
Date date = new Date();
byte[] cover = new byte[]{2,3,4,5,6,7,8,9};
Book book = new Book(name, date, cover);
Review r1 = new Review(name);
Review r2 = new Review(name);
Review r3 = new Review(name);
Author a1 = new Author(name, null);
Author a2 = new Author(name, null);
r1.setAuthor(a1);
r2.setAuthor(a1);
r3.setAuthor(a2);
ArrayList reviews = new ArrayList();
reviews.add(r1);
reviews.add(r2);
reviews.add(r3);
book.setReviews(reviews);
ArrayList authors = new ArrayList();
authors.add(a1);
authors.add(a2);
book.setAuthors(authors);
TransactionExt tx = (TransactionExt) odmg.newTransaction();
tx.begin();
database.makePersistent(book);
tx.commit();
Integer versionBook = book.getVersion();
tx.begin();
tx.getBroker().clearCache();
OQLQuery query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
Collection result = (Collection) query.execute();
assertEquals(1, result.size());
Book b = (Book) result.iterator().next();
assertEquals(versionBook, b.getVersion());
assertNotNull(b.getReviews());
assertEquals(3, b.getReviews().size());
assertNotNull(((Review) b.getReviews().get(0)).getAuthor());
assertNotNull(((Review) b.getReviews().get(1)).getAuthor());
assertNotNull(((Review) b.getReviews().get(2)).getAuthor());
assertNotNull(b.getAuthors());
assertEquals(2, b.getAuthors().size());
Author newA = (Author) b.getAuthors().get(0);
boolean failed = true;
for(Iterator iterator = b.getReviews().iterator(); iterator.hasNext();)
{
Review review = (Review) iterator.next();
if(newA.equals(review.getAuthor()))
{
// as we have circular references we expect the same object instance
assertSame(newA, review.getAuthor());
failed = false;
}
}
if(failed) fail("Expect the same object instance, but not found for " + newA);
// Book instance should be already locked
// now mark Book for delete and disable cascading delete
// for the 1:n relation to Review class
tx.setCascadingDelete(Book.class, "reviews", false);
database.deletePersistent(b);
tx.commit();
tx.begin();
tx.getBroker().clearCache();
query = odmg.newOQLQuery();
query.create("select reviews from " + Review.class.getName() + " where summary like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
// we auto-delete the Review object, only remove from reference collection
assertEquals(3, result.size());
List list = new ArrayList(result);
assertNotNull(((Review) list.get(0)).getAuthor());
assertNotNull(((Review) list.get(1)).getAuthor());
assertNotNull(((Review) list.get(2)).getAuthor());
Review newR1 = (Review) list.get(0);
// book was deleted so we expect unlink of FK
assertNull(newR1.getFkBook());
newA = ((Review) list.get(0)).getAuthor();
assertEquals(0, newA.getBooks().size());
tx.begin();
query = odmg.newOQLQuery();
query.create("select books from " + Book.class.getName() + " where title like $1");
query.bind(name);
result = (Collection) query.execute();
tx.commit();
assertEquals(0, result.size());
}
//=======================================================
// inner test classes
//=======================================================
public static final class Book implements Serializable
{
private Integer id;
private String title;
private Date publicationDate;
private byte[] cover;
private Integer version;
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 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 final class Author implements Serializable
{
private Integer id;
private String name;
private List books;
private Integer version;
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 List getBooks()
{
return books;
}
public void setBooks(List books)
{
this.books = books;
}
public Integer getVersion()
{
return version;
}
public void setVersion(Integer version)
{
this.version = version;
}
}
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 static final class PublisherImpl implements Publisher
{
private Integer id;
private String name;
private Integer version;
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 static final class Review implements Serializable
{
private Integer id;
private String summary;
private Integer fkBook;
private Integer version;
private Author author;
public Review()
{
}
public Review(String summary)
{
this.summary = summary;
}
public Integer getId()
{
return id;
}
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 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;
}
}
}