You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by Maksimenko Alexander <ma...@bird.cris.net> on 2004/08/12 17:43:37 UTC

nested prefetched relationships

Hi!
I use 1.0rc6
I find out that prefetched relationships don't work with nested 
properties "property1.property2".
Is this feature realized in 1.0 or are you planning to do this in 1.1 ?

-- 
Maksimenko Alexander
Softwarium, www.softwarium.net


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


Re: Autoincriment FK and PK problem

Posted by Armin Waibel <ar...@apache.org>.
Brian Latimer wrote:
> 
>> in a DB2 databse
> 
> 
>> Table A has a PK named id that is also an identity (autoincriment) column
> 
> 
> Table B has a PK called id that is also a FK to table A's id field
> 
> When attempting to insert Class A, which contains an instance of Class 
> B, it seems that OJB attempts to insert class B before class A.

right, this is current behavior.

>  This 
> fails, as class A doesn't have a proper PK yet, and thus class B doesn't 
> have a valid PK yet.
>

Workaround for PB-api could be, first do PB.store(A) (without referenced 
object), then set PK from in reference B and do PB.store(B) or set 
reference in A and store A again.


> given that I can't change my poorly designed database, is there anything 
> I can do within OJB to get around this problem?
> 
> Do I simply need to manually insert class A and B?

Of course you can use OJB, but you have to prepare the B objects before 
insert (update, delete will work). Currently OJB isn't smart enough to 
handle this automatic. But it shouldn't be a problem to enhance OJB to 
support this.


>  That would be a 
> shame, as the auto-update feature works great for instances of class A 
> and B that already exist.
>
> any suggestions would be appriciated.
> 

Please make a feature request. I think you are right, OJB should be able 
handle this, e.g. by introduce a setting in metadata specify that B PK 
has a FK to A PK). In that case the order will be interchanged and OJB 
first store the main object and then the 1:1 reference.

regards,
Armin


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


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


Re: Autoincriment FK and PK problem

Posted by Armin Waibel <ar...@apache.org>.
Hi,

AFAIK has the order of operations not changed (the last ten releases).
If you store an object with 1:1 and 1:n references (and auto-update is
true/object) OJB do:

- first store the 1:1 references, because we need the PK values as FK in
main object
- set the 1:1 reference FK value and store the main object
- set the FK values in the 1:n references (the PK values of the main object)
- store the 1:n references

How should we change this order?

>>would it break anything if we stored the 1:1 references last, or just
>>before the 1:n references?

yep, see above.

>>
>>I know making this move would solve my odd PK problem, but would it 
 >>break
>>things for others?

If you don't use auto-update true/object/link and set the FK values by your
own (or use the OJB-link methods) it is possible to change the order.

regards,
Armin


Edson Carlos Ericksson Richter wrote:

> I'm having this problem too... When (or in what version) this order of
> operations has changed?
> 
> Thanks,
> 
> Richter
> 
> 
> Em Qui, 2004-08-26 às 15:38, Brian Latimer escreveu:
> 
>>>I've noted that when storing an object, the first step done is to store 
>>>the 1 to 1 references, then the object itself is stored and then finally, 
>>>the 1 to n or m to n references are stored.
>>
>>
>>Is there a reason for this order of operations?
>>
>>would it break anything if we stored the 1:1 references last, or just 
>>before the 1:n references?
>>
>>I know making this move would solve my odd PK problem, but would it break 
>>things for others?
>>
>>
>>Code follows:
>>****************************************************************************************************************
>>
>>     private void storeToDb(Object obj, ClassDescriptor cld, Identity oid, 
>>boolean insert)
>>     {
>>         // 1. link and store 1:1 references
>>         storeReferences(obj, cld, insert);
>>
>>         Object[] pkValues = oid.getPrimaryKeyValues();
>>         if (!serviceBrokerHelper().assertValidPkFields(cld.getPkFields(), 
>>pkValues))
>>         {
>>             // BRJ: fk values may be part of pk, but the are not known during
>>             // creation of Identity. so we have to get them here
>>             pkValues = serviceBrokerHelper().getKeyValues(cld, obj);
>>             if 
>>(!serviceBrokerHelper().assertValidPkFields(cld.getPkFields(), pkValues))
>>             {
>>                 String append = insert ? " on insert" : " on update" ;
>>                 throw new PersistenceBrokerException("assertValidPkFields 
>>failed for Object of type: " + cld.getClassNameOfObject() + append);
>>             }
>>         }
>>
>>         // setreferenceFKs for auto_inc dbs - this can be ignored by hi 
>>low or any that do pre assignment
>>         try
>>         {
>>             sequenceManager.setReferenceFKs(obj, cld);
>>         }
>>         catch (SequenceManagerException e)
>>         {
>>             logger.error("Setting of reference FK failed", e);
>>             throw new PersistenceBrokerException(e);
>>         }
>>         // get super class cld then store it with the object
>>         /*
>>         now for multiple table inheritance
>>         1. store super classes, topmost parent first
>>         2. go down through heirarchy until current class
>>         3. todo: store to full extent?
>>
>>         This if-clause will go up the inheritance heirarchy to store all 
>>the super classes.
>>         The id for the top most super class will be the id for all the 
>>subclasses too
>>          */
>>         if(cld.getSuperClass() != null)
>>         {
>>
>>             ClassDescriptor superCld = 
>>getDescriptorRepository().getDescriptorFor(cld.getSuperClass());
>>             storeToDb(obj, superCld, oid, insert);
>>             // arminw: why this?? I comment out this section
>>             // storeCollections(obj, cld.getCollectionDescriptors(), insert);
>>         }
>>
>>         // 2. store primitive typed attributes (Or is THIS step 3 ?)
>>         // if obj not present in db use INSERT
>>         if (insert)
>>         {
>>             dbAccess.executeInsert(cld, obj);
>>             // Let SequenceManager update id if necessary, should only 
>>happen after an insert
>>             try
>>             {
>>                 sequenceManager.afterStore(dbAccess, cld, obj);
>>             }
>>             catch (SequenceManagerException e)
>>             {
>>                 logger.error("SQLException during 
>>SequenceManager.afterStore call on object '"
>>                         + cld.getClassOfObject().getName() + "': " + 
>>e.getMessage(), e);
>>                 throw new PersistenceBrokerException(e);
>>             }
>>         }
>>         // else use UPDATE
>>         else
>>         {
>>             dbAccess.executeUpdate(cld, obj);
>>         }
>>         // Create a new Identity based on the current set of primary key 
>>values.
>>         Identity newOid = new Identity(obj, this, cld);
>>         // cache object for symmetry with getObjectByXXX()
>>         // Add the object to the cache.
>>         objectCache.cache(newOid, obj);
>>         // 3. store 1:n and m:n associations
>>         storeCollections(obj, cld, insert);
>>     }
>>
>>
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
>>For additional commands, e-mail: ojb-user-help@db.apache.org
>>
>>
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org
> 
> 
> 


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


Re: Autoincriment FK and PK problem

Posted by Edson Carlos Ericksson Richter <ed...@mgrinformatica.com.br>.
I'm having this problem too... When (or in what version) this order of
operations has changed?

Thanks,

Richter


Em Qui, 2004-08-26 às 15:38, Brian Latimer escreveu:
> >I've noted that when storing an object, the first step done is to store 
> >the 1 to 1 references, then the object itself is stored and then finally, 
> >the 1 to n or m to n references are stored.
> 
> 
> Is there a reason for this order of operations?
> 
> would it break anything if we stored the 1:1 references last, or just 
> before the 1:n references?
> 
> I know making this move would solve my odd PK problem, but would it break 
> things for others?
> 
> 
> Code follows:
> ****************************************************************************************************************
> 
>      private void storeToDb(Object obj, ClassDescriptor cld, Identity oid, 
> boolean insert)
>      {
>          // 1. link and store 1:1 references
>          storeReferences(obj, cld, insert);
> 
>          Object[] pkValues = oid.getPrimaryKeyValues();
>          if (!serviceBrokerHelper().assertValidPkFields(cld.getPkFields(), 
> pkValues))
>          {
>              // BRJ: fk values may be part of pk, but the are not known during
>              // creation of Identity. so we have to get them here
>              pkValues = serviceBrokerHelper().getKeyValues(cld, obj);
>              if 
> (!serviceBrokerHelper().assertValidPkFields(cld.getPkFields(), pkValues))
>              {
>                  String append = insert ? " on insert" : " on update" ;
>                  throw new PersistenceBrokerException("assertValidPkFields 
> failed for Object of type: " + cld.getClassNameOfObject() + append);
>              }
>          }
> 
>          // setreferenceFKs for auto_inc dbs - this can be ignored by hi 
> low or any that do pre assignment
>          try
>          {
>              sequenceManager.setReferenceFKs(obj, cld);
>          }
>          catch (SequenceManagerException e)
>          {
>              logger.error("Setting of reference FK failed", e);
>              throw new PersistenceBrokerException(e);
>          }
>          // get super class cld then store it with the object
>          /*
>          now for multiple table inheritance
>          1. store super classes, topmost parent first
>          2. go down through heirarchy until current class
>          3. todo: store to full extent?
> 
>          This if-clause will go up the inheritance heirarchy to store all 
> the super classes.
>          The id for the top most super class will be the id for all the 
> subclasses too
>           */
>          if(cld.getSuperClass() != null)
>          {
> 
>              ClassDescriptor superCld = 
> getDescriptorRepository().getDescriptorFor(cld.getSuperClass());
>              storeToDb(obj, superCld, oid, insert);
>              // arminw: why this?? I comment out this section
>              // storeCollections(obj, cld.getCollectionDescriptors(), insert);
>          }
> 
>          // 2. store primitive typed attributes (Or is THIS step 3 ?)
>          // if obj not present in db use INSERT
>          if (insert)
>          {
>              dbAccess.executeInsert(cld, obj);
>              // Let SequenceManager update id if necessary, should only 
> happen after an insert
>              try
>              {
>                  sequenceManager.afterStore(dbAccess, cld, obj);
>              }
>              catch (SequenceManagerException e)
>              {
>                  logger.error("SQLException during 
> SequenceManager.afterStore call on object '"
>                          + cld.getClassOfObject().getName() + "': " + 
> e.getMessage(), e);
>                  throw new PersistenceBrokerException(e);
>              }
>          }
>          // else use UPDATE
>          else
>          {
>              dbAccess.executeUpdate(cld, obj);
>          }
>          // Create a new Identity based on the current set of primary key 
> values.
>          Identity newOid = new Identity(obj, this, cld);
>          // cache object for symmetry with getObjectByXXX()
>          // Add the object to the cache.
>          objectCache.cache(newOid, obj);
>          // 3. store 1:n and m:n associations
>          storeCollections(obj, cld, insert);
>      }
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org
> 
> 


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


Re: Autoincriment FK and PK problem

Posted by Brian Latimer <bl...@apcc.aspca.org>.
>I've noted that when storing an object, the first step done is to store 
>the 1 to 1 references, then the object itself is stored and then finally, 
>the 1 to n or m to n references are stored.


Is there a reason for this order of operations?

would it break anything if we stored the 1:1 references last, or just 
before the 1:n references?

I know making this move would solve my odd PK problem, but would it break 
things for others?


Code follows:
****************************************************************************************************************

     private void storeToDb(Object obj, ClassDescriptor cld, Identity oid, 
boolean insert)
     {
         // 1. link and store 1:1 references
         storeReferences(obj, cld, insert);

         Object[] pkValues = oid.getPrimaryKeyValues();
         if (!serviceBrokerHelper().assertValidPkFields(cld.getPkFields(), 
pkValues))
         {
             // BRJ: fk values may be part of pk, but the are not known during
             // creation of Identity. so we have to get them here
             pkValues = serviceBrokerHelper().getKeyValues(cld, obj);
             if 
(!serviceBrokerHelper().assertValidPkFields(cld.getPkFields(), pkValues))
             {
                 String append = insert ? " on insert" : " on update" ;
                 throw new PersistenceBrokerException("assertValidPkFields 
failed for Object of type: " + cld.getClassNameOfObject() + append);
             }
         }

         // setreferenceFKs for auto_inc dbs - this can be ignored by hi 
low or any that do pre assignment
         try
         {
             sequenceManager.setReferenceFKs(obj, cld);
         }
         catch (SequenceManagerException e)
         {
             logger.error("Setting of reference FK failed", e);
             throw new PersistenceBrokerException(e);
         }
         // get super class cld then store it with the object
         /*
         now for multiple table inheritance
         1. store super classes, topmost parent first
         2. go down through heirarchy until current class
         3. todo: store to full extent?

         This if-clause will go up the inheritance heirarchy to store all 
the super classes.
         The id for the top most super class will be the id for all the 
subclasses too
          */
         if(cld.getSuperClass() != null)
         {

             ClassDescriptor superCld = 
getDescriptorRepository().getDescriptorFor(cld.getSuperClass());
             storeToDb(obj, superCld, oid, insert);
             // arminw: why this?? I comment out this section
             // storeCollections(obj, cld.getCollectionDescriptors(), insert);
         }

         // 2. store primitive typed attributes (Or is THIS step 3 ?)
         // if obj not present in db use INSERT
         if (insert)
         {
             dbAccess.executeInsert(cld, obj);
             // Let SequenceManager update id if necessary, should only 
happen after an insert
             try
             {
                 sequenceManager.afterStore(dbAccess, cld, obj);
             }
             catch (SequenceManagerException e)
             {
                 logger.error("SQLException during 
SequenceManager.afterStore call on object '"
                         + cld.getClassOfObject().getName() + "': " + 
e.getMessage(), e);
                 throw new PersistenceBrokerException(e);
             }
         }
         // else use UPDATE
         else
         {
             dbAccess.executeUpdate(cld, obj);
         }
         // Create a new Identity based on the current set of primary key 
values.
         Identity newOid = new Identity(obj, this, cld);
         // cache object for symmetry with getObjectByXXX()
         // Add the object to the cache.
         objectCache.cache(newOid, obj);
         // 3. store 1:n and m:n associations
         storeCollections(obj, cld, insert);
     }



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


Re: Autoincriment FK and PK problem

Posted by Fernando <fe...@ptcom.com.br>.
Hi Brian Latimer!!
Once I've used a one-to-one mapping and I do the following:

Tables:
  a.. create table A (id int primary key);
  b.. create table B (id int primary key, foreign key (id) references a (id));

respository_user.xml:
<class-descriptor class="model.A" table="LAB.A">
  <field-descriptor id="0"
    name="id"
    column="id"
    jdbc-type="INTEGER"
    primarykey="true"
  />
</class-descriptor>


<class-descriptor class="model.B" table="LAB.B">
  <field-descriptor id="0"
    name="id"
    column="id"
    jdbc-type="INTEGER"
    primarykey="true"
  />
  <reference-descriptor 
    name="a"
    class-ref="model.A"
    auto-insert="true"
    >
   <foreignkey field-ref="id"/>
  </reference-descriptor>
</class-descriptor>

So, you have to work with the child class. Instantiate a class A and associate it to a class B, then you can call the store(b) method.

A a = new A();
a.setId(1);

B b = new B();
b.setA(a);

store(b)

OJB will insert the parent first and then the child. But you can't forget the auto-insert="true" tag!!!!

Hope it helps and sorry my english,

Fernando Bernardino






----- Original Message ----- 
From: "Brian Latimer" <bl...@apcc.aspca.org>
To: "OJB Users List" <oj...@db.apache.org>
Sent: Wednesday, August 25, 2004 4:43 PM
Subject: Autoincriment FK and PK problem


> 
> >in a DB2 databse
> 
> >Table A has a PK named id that is also an identity (autoincriment) column
> 
> Table B has a PK called id that is also a FK to table A's id field
> 
> When attempting to insert Class A, which contains an instance of Class B, 
> it seems that OJB attempts to insert class B before class A.  This fails, 
> as class A doesn't have a proper PK yet, and thus class B doesn't have a 
> valid PK yet.
> 
> given that I can't change my poorly designed database, is there anything I 
> can do within OJB to get around this problem?
> 
> Do I simply need to manually insert class A and B?  That would be a shame, 
> as the auto-update feature works great for instances of class A and B that 
> already exist.
> 
> any suggestions would be appriciated.
> 
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org
> 
> 

Autoincriment FK and PK problem

Posted by Brian Latimer <bl...@apcc.aspca.org>.
>in a DB2 databse

>Table A has a PK named id that is also an identity (autoincriment) column

Table B has a PK called id that is also a FK to table A's id field

When attempting to insert Class A, which contains an instance of Class B, 
it seems that OJB attempts to insert class B before class A.  This fails, 
as class A doesn't have a proper PK yet, and thus class B doesn't have a 
valid PK yet.

given that I can't change my poorly designed database, is there anything I 
can do within OJB to get around this problem?

Do I simply need to manually insert class A and B?  That would be a shame, 
as the auto-update feature works great for instances of class A and B that 
already exist.

any suggestions would be appriciated.






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