Hi Bruce,
Thanks for your response. I made some changes to the test class and the mapping per your and Charles input (along with a bit of experimenting) and got things to work. I'll also upgrade to 0.9.4. I actually took the "many-key" completely out, so the mapping now looks like so:
<class name="Bowl" identity="bowlId" key-generator="IDENTITY" >
<description>Bowl</description>
<map-to table="BOWL"/>
<field name="bowlId" type="integer" >
<sql name="BOWL_ID" type="integer"/>
</field>
<field name="color" type="string">
<sql name="COLOR" type="varchar"/>
</field>
<field name="cherries" type="Cherry" required="true" collection="vector">
<sql many-table="BOWL_CHERRY"/>
</field>
</class>

<class name="Cherry" identity="cherryId" key-generator="IDENTITY" >
<description>Cherry</description>
<map-to table="CHERRY"/>
<field name="cherryId" type="integer" >
<sql name="CHERRY_ID" type="integer"/>
</field>
<field name="cherryType" type="string">
<sql name="CHERRY_TYPE" type="varchar"/>
</field>
</class>
which seems to work fine (without or without the key).
The test class goes like so:

// Get a bowl of cherries
Bowl cleanBowl = this.getBowl();
Cherry cherryOne = this.pickCherry();
Cherry cherryTwo = this.pickCherry();
cleanBowl.addCherry(cherryOne);
cleanBowl.addCherry(cherryTwo);

// Put the bowl in the fridge

// Charles solution
db.begin();
db.create(cleanBowl);
db.create(cherryOne);
db.create(cherryTwo);
bowlId = (Integer)db.getIdentity(cleanBowl);
db.commit();
db.close();

// Bruces solution
db.setAutoStore(true);
db.begin();
db.create(cleanBowl);
bowlId = (Integer)db.getIdentity(cleanBowl);
db.commit();
db.close();

The key (pun intended) seemed to be having the bowl and cherries in the same transaction as Charles pointed out, or having setAutoStore( true ) as you pointed out.

I'm very curious about your statement "officially Castor only supports bi-directional relationships". I did not change my objects to be bi-directional, and it works fine, so I'm assuming I'm seeing some non-official feature. Is there any risk of it going away? The FAQ seems to hint that you may eventually support this "officially".

Thanks again for your response.
Regards,
Reilly Shea
BTW - I also took your advice on opening and closing a new JDBC connection in every test.


At 04:54 PM 11/9/2002 -0700, you wrote:
This one time, at band camp, Reilly Shea said:

Please see my comments inline.

RS>Help, please. I've been trying to use Castor JDO to handle collections. I
RS>tried looking at the examples but I noticed that the appearance of
RS>"many-table" is commented out in all the example mapping files. Does this
RS>mean it's broken.

The many-to-many relationship between Product and Castegory is
uncommented and works just fine in the lastest version of Castor.
Upgrade from 0.9.3.21 to either 0.9.4 or the CVS version.

RS>I've got a simple object "Bowl", which has a collection (Vector) of
RS>Cherries. Below is the mapping file, and source code for the objects, along
RS>with a test class. The test class does the following:
RS>
RS>-creates a bowl and saves it to the DB
RS>-loads the just created bowl from the DB
RS>-creates a cherry and saves it to the DB
RS>-loads the just created cherry from the DB
RS>-adds the cherry to the bowl
RS>-saves the bowl to the DB
RS>
RS>When I save the bowl to the DB in the last step, I'm expecting an entry to
RS>be made to the table "BOWL_CHERRY" but it never
RS>happens.
RS>Example: if I create a bowl (bowlId=10) with two cherries in it
RS>(cherryId=5, and cherryId=6) and then save the bowl to the
RS>DB. I would expect an entry in the BOWL_CHERRY table as follows:
RS>BOWL_ID CHERRY_ID
RS>10 5
RS>10 6
RS>
RS>The entries in the BOWL, and CHERRY are created just as I would expect.
RS>Is my mapping file wrong? Does castor support this? Am I on crack? I've
RS>beat on this for quite a while with no success.
...
RS> <class name="Bowl" identity="bowlId" key-generator="IDENTITY" >
...
RS> <field name="cherries" type="Cherry" required="true"
RS>collection="vector" get-method="getCherries"
RS>
RS>set-method="setCherries">
RS> <sql many-table="BOWL_CHERRY" many-key="CHERRY_ID"/>
^^^^^^^^^
The many-key attribute above should actually be BOWL_ID, not CHERRY_ID.

RS> </field>
RS> </class>
RS>
RS> <class name="Cherry" identity="cherryId" key-generator="IDENTITY" >

There is no relationship with the Bowl object here in the Cherry object.

RS> <map-to table="CHERRY"/>
RS> <field name="cherryId" type="integer" >
RS> <sql name="CHERRY_ID" type="integer" many-table="BOWL_CHERRY"
RS>many-key="CHERRY_ID"/>
RS> </field>
RS> <field name="cherryType" type="string">
RS> <sql name="CHERRY_TYPE" type="varchar"/>
RS> </field>
RS> </class>
RS></mapping>
RS>
RS>#############
RS>DB SQL (Hypersonic)
RS>
RS>CREATE TABLE BOWL(BOWL_ID INTEGER NOT NULL IDENTITY PRIMARY KEY ,COLOR
RS>VARCHAR(100));

Where is the CHERRY_ID in the table above?

RS>CREATE TABLE CHERRY(CHERRY_ID INTEGER NOT NULL IDENTITY PRIMARY KEY
RS>,CHERRY_TYPE VARCHAR(100));

Where is the BOWL_ID in the table above?

RS>CREATE TABLE BOWL_CHERRY ( BOWL_ID INTEGER ,CHERRY_ID INTEGER , FOREIGN KEY
RS>(BOWL_ID) REFERENCES BOWL(BOWL_ID), FOREIGN KEY (CHERRY_ID) REFERENCES
RS>CHERRY(CHERRY_ID) );

There's no need to place foreign key constraints on the columns in
any of the tables above. The JDO examples demonstrate all that
you're trying to do here. Keep in mind that officially Castor only
supports bi-directional relationships
(http://www.castor.org/jdo-faq.html#bi-directional).

...

RS>public class Cherry implements org.exolab.castor.jdo.TimeStampable {
RS>
RS> private String cherryType;
RS> private Integer cherryId;
RS> private long jdoTimeStamp;

You've got a reference to the Cherry object from within the Bowl
object, but there is no reference here in the Cherry object to the
Bowl object. This coincides with my comment about the mapping of
the Cherry object above.

RS> public Cherry() {
RS> }
RS>
RS> public long jdoGetTimeStamp() {
RS> return this.jdoTimeStamp;
RS> }
RS>
RS> public void jdoSetTimeStamp(long aTimestamp) {
RS> this.jdoTimeStamp = aTimestamp;
RS> }
RS> public void setCherryType(String aCherryType) {
RS> this.cherryType = aCherryType;
RS> }
RS> public String getCherryType() {
RS> return this.cherryType;
RS> }
RS> public Integer getCherryId() {
RS> return this.cherryId;
RS> }
RS> public void setCherryId(Integer anInteger) {
RS> this.cherryId = anInteger;
RS> }
RS>}

...

RS> // Add the test cherry to the bowl
RS> this.testBowl.addCherry(testCherry);
RS> System.out.println("Added test cherry to bowl.");
RS> System.out.println("Cherry in bowl id is: " +
RS>((Cherry)testBowl.getCherries().iterator().next()).getCherryId());
RS>
RS> // Save the bowl to the DB
RS> try {
RS> // Obtain a new database
RS> db = jdo.getDatabase();
RS> // Begin a transaction
RS> db.begin();
RS> // Make it persistent
RS> db.update( testBowl );

Depending on how extensive an object graph is, you may need to use
setAutoStore( true ) so that all reachable objects within the
transaction get committed.

RS> //bowlId = (Integer)db.getIdentity(testBowl);
RS> db.commit();
RS> db.close();
RS> } catch ( Exception e ) {
RS> e.printStackTrace();
RS> }
RS>
RS> }
RS>
RS> public static void main(String[] args) {
RS> junit.textui.TestRunner.run(BowlTest.class);
RS> }
RS>
RS>}

You realize that this test is opening and closing a new JDBC
connection in every test (LOTS of overhead). For performance reasons
I would set up the Database object as a member variable in the test
and not call close() until all tests have executed.

Please check out the JDO examples since 0.9.4 and use the many-to-many
example as a reference for your work. You're almost there, you just
need the bi-directional relationships and the correct many-key in
the mapping for the Bowl object.

Bruce
--

perl -e 'print unpack("u30","<0G)U8V4\@4VYY9&5R\"F9E<G)E=\$\!F<FEI+F-O;0\`\`");'

-----------------------------------------------------------
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
unsubscribe castor-dev
----------------------------------------------------------- If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
unsubscribe castor-dev

Reply via email to