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: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
