In all cases, the only writes to table A_B are to delete all rows that reference the new A.
I've had a look through the OJB test cases, and so far the only places I see n:m associations being exercised, they are set up as part of the construction of the instance; I don't see any test which alter the content of a collection that's part of an n:m mapping. Are there any?
If anybody is successfully using non-decomposed n:m mappings in OJB can you give me sample code demonstrating how to do it?
L.
Laurie Harper wrote:
Doing some further digging, I found a bug in the test case: it was missing 'tx3.lock(a1, Transaction.WRITE);' in the collection update transaction block. However, adding this had no effect on behaviour. Here's what's in the log for that block of code:22981 DEBUG [main] odmg.ObjectEnvelopeTable - call beginTransaction() on PB instance 22981 DEBUG [main] accesslayer.ConnectionManager - Try to change autoCommit state to 'false' 22983 DEBUG [main] ta.PersistenceBrokerFactoryDefaultImpl - createPersistenceBroker(key) called 22983 DEBUG [main] singlevm.PersistenceBrokerImpl - PB.close was called: org.apache.ojb.broker.singlevm.PersistenceBrokerImpl@2c2cfd 22984 DEBUG [main] odmg.ObjectEnvelopeTable - commit: A{272}(org.apache.ojb.odmg.states.StateOldClean) 22985 DEBUG [main] ta.PersistenceBrokerFactoryDefaultImpl - createPersistenceBroker(key) called 22985 DEBUG [main] singlevm.PersistenceBrokerImpl - PB.close was called: org.apache.ojb.broker.singlevm.PersistenceBrokerImpl@2c2cfd 22986 DEBUG [main] odmg.TransactionImpl - Commit transaction org.apache.ojb.odmg.TransactionImpl@74ba2a, commit on broker org.apache.ojb.broker.singlevm.PersistenceBrokerImpl@30fecf 22988 DEBUG [main] ta.PersistenceBrokerFactoryDefaultImpl - createPersistenceBroker(key) called 22989 DEBUG [main] singlevm.PersistenceBrokerImpl - PB.close was called: org.apache.ojb.broker.singlevm.PersistenceBrokerImpl@2c2cfd 22990 DEBUG [main] locking.LockManagerDefaultImpl - LM.releaseLock(tx-192.168.1.100:14224e:f22ecbeafa:-7ffe, A{272}) 22990 DEBUG [main] ta.PersistenceBrokerFactoryDefaultImpl - createPersistenceBroker(key) called 22990 DEBUG [main] singlevm.PersistenceBrokerImpl - PB.close was called: org.apache.ojb.broker.singlevm.PersistenceBrokerImpl@2c2cfd 22992 DEBUG [main] odmg.TransactionImpl - Close Transaction and release current PB org.apache.ojb.broker.singlevm.PersistenceBrokerImpl@30fecf on tx org.apache.ojb.odmg.TransactionImpl@74b a2a The changes to a1's collection of Bs never results in an update on table A (which it shouldn't in this case, of course) or an insert on table A_B (which it should). I tried calling tx3.lock(bs, Transaction.WRITE) before modifying bs, but that resulted in a 'not persistence capable' exception. I'm sure I must be missing something really simple... Help! L. Laurie Harper wrote: > This is driving me slightly nuts :-) I ran into a strange error tring to > add a collection property modelled by an indirection table in the > database. If I do this (much abreviated): > > tx = odmg.newTransaction(); > tx.begin(); > tx.lock(project, WRITE); > project.getList().add(foo); > tx.commit(); > > where the getList() method initialises the collection property to 'new > LinkedList()' if it's not already set, I get an error about there being > no transaction in progress. That's the problem I want to solve. > > > In trying to understand what's going on, I tried to boil it down to a > really simple test case. The test case consists of two classes and three > tables modelling an n:m relationship. The problem is, it breaks in a > different way than the above: when I add items to the collection > property and commit, the indirection table isn't updated (so the > collection property doesn't get persisted). > > The test case involves two simple classes, A and B. A has a collection > of B. The database contains tables A and B and an indirection table A_B. > I can load an instance of A from the database and OJB uses rows from A_B > to populate A's collection property. But if I try and modify the > collection property on A, nothing is written to the A_B table. Here's > the various files that constitute my test case. Any suggestions what I'm > doing wrong may help shed light on real problem, described above. > > One oddity is that the query to load the AB instances only works if I > use the SQL table/column names in the OQL query! (see lines marked XXX > in the test case below). I'm unclear about why that should be... > > Schema: > > CREATE SEQUENCE A_SEQ; > CREATE SEQUENCE B_SEQ; > CREATE SEQUENCE A_B_SEQ; > > CREATE TABLE A > ( > ID INTEGER DEFAULT nextval('A_SEQ') NOT NULL, > PRIMARY KEY (ID) > ); > > CREATE TABLE B > ( > ID INTEGER DEFAULT nextval('B_SEQ') NOT NULL, > PRIMARY KEY (ID) > ); > > > CREATE TABLE A_B > ( > A_ID INTEGER DEFAULT nextval('A_B_SEQ') NOT NULL, > B_ID INTEGER DEFAULT nextval('A_B_SEQ') NOT NULL, > PRIMARY KEY (A_ID,B_ID) > ); > > ALTER TABLE A_B > ADD CONSTRAINT A_FK_1 FOREIGN KEY (A_ID) REFERENCES A (ID) > ; > ALTER TABLE A_B > ADD CONSTRAINT A_FK_2 FOREIGN KEY (B_ID) REFERENCES B (ID) > ; > > Repository_user.xml entries: > > > > > > > > > > > > > > > > > > > > > Object model: > > import java.util.List; > import java.util.LinkedList; > > /** > * A has n:m relationship with B > */ > public class A { > private int id; > public int getID() { > return id; > } > > private List listOfB; > public List getListOfB() { > return (null == listOfB) ? new LinkedList() : listOfB; > } > } > > /* --- */ > > import java.util.List; > > /** > * B has m:n relationship with A > */ > public class B { > private int id; > public int getID() { > return id; > } > } > > /* --- */ > > import java.util.List; > import java.util.LinkedList; > > /** > * Expose the A_B table so we can query it in the test cases. > */ > public class AB { > private int aID, bID; > public int getAID() { > return aID; > } > public int getBID() { > return bID; > } > } > > Test case: > > import java.util.List; > > import org.odmg.*; > import org.apache.ojb.odmg.OJB; > import junit.framework.TestCase; > import junit.framework.TestSuite; > import junit.framework.Test; > import junit.textui.TestRunner; > > /** > * Creates instances of A and B that reference each other and persists > them. > */ > public class RelationshipTest extends TestCase { > private Implementation odmg; > private Database db; > > public static void main(String[] args) { > TestRunner.run(RelationshipTest.class); > } > public static Test suite() { > return new TestSuite(RelationshipTest.class); > } > public RelationshipTest(String name) { > super(name); > } > > public void setUp() throws ODMGException { > System.out.println("setup"); > odmg = OJB.getInstance(); > db = odmg.newDatabase(); > db.open("repository.xml", Database.OPEN_READ_WRITE); > } > > public void testCreate() throws Exception { > A a1; > B b1, b2; > > // Create instances of B to be associated with an A > { > Transaction tx1 = odmg.newTransaction(); > tx1.begin(); > b1 = new B(); > b2 = new B(); > tx1.lock(b1, Transaction.WRITE); > tx1.lock(b2, Transaction.WRITE); > tx1.commit(); > } > > // Create an instance of A > { > Transaction tx2 = odmg.newTransaction(); > tx2.begin(); > a1 = new A(); > tx2.lock(a1, Transaction.WRITE); > tx2.commit(); > } > > // Modify A's collection of Bs > { > Transaction tx3 = odmg.newTransaction(); > tx3.begin(); > List bs = a1.getListOfB(); // creates new list in a1 > bs.add(b1); > bs.add(b2); > tx3.commit(); > } > > // Check that the A_B table was populated > { > OQLQuery q = odmg.newOQLQuery(); > //q.create("select AB from AB where AB.aID = "+a1.getID());//XXX > q.create("select AB from AB where A_B.A_ID = "+a1.getID());//XXX > List abs = (DList) q.execute(); > assertNotNull("abs", abs); > assertEquals("abs.size", 2, abs.size()); > } > } > > public void testLoad() throws Exception { > OQLQuery q = odmg.newOQLQuery(); > q.create("select A from A where A.ID = 1"); > A a = (A) ((DList) q.execute()).get(0); > List listOfB = a.getListOfB(); > > assertEquals("a.id", 1, a.getID()); > assertNotNull("a.listOfB", listOfB); > assertEquals("a.bs.size", 2, listOfB.size()); > assertEquals("a.bs[0].id", 1, ((B) listOfB.get(0)).getID()); > assertEquals("a.bs[1].id", 2, ((B) listOfB.get(1)).getID()); > } > } > > > -- > To unsubscribe, e-mail: > For additional commands, e-mail: -- To unsubscribe, e-mail: For additional commands, e-mail:
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
