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 Jason McKerr <mc...@nacse.org> on 2003/06/25 18:20:36 UTC

Foreign Key column not getting updated

Hey guys,

I'm having a problem with a nullable foreign-key column not getting
updated.

I've got a table (Acknowledgements) that has a foreign key to the
Project table.  

Now if I have all of the columns set for acknowledgements (including
projectID) all of the columns except projectID are getting set when I
call store().  The projectID is getting set to null.

If I comment out the reference call to Project from the Acknowledgement
table in my repository, the column gets set normally.

So the question is: Can I not just do an insert without a complete
object reference?  I'm doing a lot of this over serialized XML so it's
not cool to have to pass an object graph just to do an isnert on a minor
related table.

Jason




Re: Foreign Key column not getting updated

Posted by Jakob Braeuchi <jb...@gmx.ch>.
hi jason,

i made some test wit references:

Person has a reference to Test. first i connect the Test from person1 to 
person2, then i add a new Test to person2.
this works when i set auto-update="true" in the reference-descriptor  !

    private void updateRef(PersistenceBroker broker)
    {
        Query query;
        Criteria crit;
        IPerson person1, person2;
        ITest testObj = null;

        crit = new Criteria();
        crit.addEqualTo("id", new Integer(1));
        query = new QueryByCriteria(Person.class, crit);
        person1 = (IPerson) broker.getObjectByQuery(query);
        testObj = person1.getTestObject();

        crit = new Criteria();
        crit.addEqualTo("id", new Integer(3));
        query = new QueryByCriteria(Person.class, crit);
        person2 = (IPerson) broker.getObjectByQuery(query);

        // connect existing TestObj of person1
        person2.setTestObject(testObj);
        broker.store(person2);
        broker.clearCache();

        crit = new Criteria();
        crit.addEqualTo("id", new Integer(3));
        query = new QueryByCriteria(Person.class, crit);
        person2 = (IPerson) broker.getObjectByQuery(query);

        testObj = person2.getTestObject();
       
        // connect to a new TestObj
        Test testObj1 = new Test();
        testObj1.setId(new Integer(77));
        testObj1.setTest("New TestObj 77");
        person2.setTestObject(testObj1);
        broker.store(person2);

-----

   <class-descriptor
      class="brj.ojb.Person"
      table="tabPerson"
   >
...
       <field-descriptor
         name="idTest"
         column="idTest"
         jdbc-type="INTEGER"
      />
....
      <reference-descriptor
         name="testObject"
         class-ref="brj.ojb.Test"
         proxy="false"
         auto-update="true"
         >
         <foreignkey field-ref="idTest"/>
      </reference-descriptor>
....

  <class-descriptor
      class="brj.ojb.Test"
      table="tabTest"
    >
      <field-descriptor id="1"
         name="id"
         column="id"
         jdbc-type="INTEGER"
         primarykey="true"
         autoincrement="true"
      />
      <field-descriptor id="2"
         name="test"
         column="test"
         jdbc-type="VARCHAR"
      />

    </class-descriptor>

hth
jakob

Jason McKerr wrote:

>OK, I've done some more testing.  Basically I'm finding that
>
>a) If the foreign key datatype is a primitive (int) it works fine, but
>you can't null it
>
>OR 
>
>b) If it's not a primitive, the reference (reference-descriptor) object
>MUST exist and be set for the foreign-key to persist.  That means I have
>two choices:
>
>1) Switch to primitives
>2) do runtime checks.  As in, 
>	if (fkID != null) {
>		Object a = new Object();
>		a.setPK(fkID);
>	}
>broker.store(this);
>
>Included is the Java file (attached) and the snippet from my
>repository.xml.
>
>Thanks,
>
>Jason
>
>----------------Snippet----------------------------------
>
>
>
><!-- Definitions for org.nacse.nees.data.project.Acknowledgement -->
>  <class-descriptor class="org.nacse.nees.data.project.Acknowledgement"
>table="ACKNOWLEDGEMENT">
>    <field-descriptor name="ackID" column="ACKID" jdbc-type="INTEGER"
>primarykey="true" autoincrement="true" sequence-name="ackSeq"/>
>    <field-descriptor name="projectID" column="PROJECTID"
>jdbc-type="INTEGER"
>conversion="org.apache.ojb.broker.accesslayer.conversions.Int2IntegerFieldConversion"/>
>    <field-descriptor name="acknowledgements" column="ACKNOWLEDGEMENTS"
>jdbc-type="VARCHAR"/>
>    <field-descriptor name="sponsors" column="SPONSORS"
>jdbc-type="VARCHAR"/>
>    <field-descriptor name="ackOptLock" column="ACKOPTLOCK"
>jdbc-type="INTEGER" locking="true"/>
>    <reference-descriptor
>      name="projectRef"
>      class-ref="org.nacse.nees.data.project.Project"
>      auto-retrieve="false"
>      auto-update="false"
>      auto-delete="false">
>      <foreignkey field-ref="projectID"/>
>    </reference-descriptor>
>  </class-descriptor>
>
>
>
>
>
>
>
>
>
>
>
>
>
>On Wed, 2003-06-25 at 10:11, Jakob Braeuchi wrote:
>  
>
>>hi jason,
>>
>>i'd prefer the wrappers. primitives are bad.
>>could you please provide your class and repository.
>>
>>jakob
>>
>>Jason McKerr wrote:
>>
>>    
>>
>>>OK, looking at the repository.dtd file, it seems that reference
>>>descriptors cannot be a wrapper datatype (Integer).  It must be
>>>primitive.  Does that mean I can't have a nullable foreign key? I know
>>>that's unusual, but it's not that unusual.
>>>
>>>Switching to an int made it work, but now it's required.  Is there a way
>>>around this? Using a conversion?
>>>
>>>Jason
>>>
>>>
>>>On Wed, 2003-06-25 at 09:20, Jason McKerr wrote:
>>> 
>>>
>>>      
>>>
>>>>Hey guys,
>>>>
>>>>I'm having a problem with a nullable foreign-key column not getting
>>>>updated.
>>>>
>>>>I've got a table (Acknowledgements) that has a foreign key to the
>>>>Project table.  
>>>>
>>>>Now if I have all of the columns set for acknowledgements (including
>>>>projectID) all of the columns except projectID are getting set when I
>>>>call store().  The projectID is getting set to null.
>>>>
>>>>If I comment out the reference call to Project from the Acknowledgement
>>>>table in my repository, the column gets set normally.
>>>>
>>>>So the question is: Can I not just do an insert without a complete
>>>>object reference?  I'm doing a lot of this over serialized XML so it's
>>>>not cool to have to pass an object graph just to do an isnert on a minor
>>>>related table.
>>>>
>>>>Jason
>>>>
>>>>
>>>>
>>>>
>>>>---------------------------------------------------------------------
>>>>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
>>    
>>
>>------------------------------------------------------------------------
>>
>>package org.nacse.nees.data.project ;
>>
>>import org.apache.ojb.broker.query.Query;
>>import org.apache.ojb.broker.query.QueryByCriteria;
>>import org.apache.ojb.broker.PersistenceBroker;
>>import org.apache.log4j.Logger;
>>import org.nacse.nees.data.DataObjectPBroker;
>>
>>import java.util.Collection;
>>import java.io.Serializable;
>>
>>public class Acknowledgement extends DataObjectPBroker implements Serializable  {
>>
>>  private Integer ackID;
>>  private Integer projectID;
>>  private String acknowledgements;
>>  private String sponsors;
>>  private Project projectRef;
>>  private Integer ackOptLock;
>>
>>  static Logger log = Logger.getLogger(Acknowledgement.class);
>>
>>  public Acknowledgement() {
>>  }
>>  public Acknowledgement(Integer ackID,
>>                         Integer projectID,
>>                         String acknowledgements,
>>                         String sponsors) {
>>    this.ackID = ackID;
>>    this.projectID = projectID;
>>    this.acknowledgements = acknowledgements;
>>    this.sponsors = sponsors;
>>  }
>>
>>  public Integer getAckID() {
>>    return ackID;
>>  }
>>  public void setAckID(Integer ackID) {
>>    this.ackID = ackID;
>>  }
>>  public Integer getProjectID() {
>>    return projectID;
>>  }
>>  public void setProjectID(Integer projectID) {
>>    this.projectID = projectID;
>>  }
>>  public String getAcknowledgements() {
>>    return acknowledgements;
>>  }
>>  public void setAcknowledgements(String acknowledgements) {
>>    this.acknowledgements = acknowledgements;
>>  }
>>  public String getSponsors() {
>>    return sponsors;
>>  }
>>  public void setSponsors(String sponsors) {
>>    this.sponsors = sponsors;
>>  }
>>  public Project getProjectRef() {
>>    return projectRef;
>>  }
>>  public void setProjectRef(Project projectRef) {
>>    this.projectRef = projectRef;
>>  }
>>  public Integer getAckOptLock() {
>>    return ackOptLock;
>>  }
>>  public void setAckOptLock(Integer ackOptLock) {
>>    this.ackOptLock = ackOptLock;
>>  }
>>
>>  public Collection listAllAcks() throws Exception {
>>    Query query = new QueryByCriteria(Acknowledgement.class, null);
>>    PersistenceBroker broker = super.getDefaultBroker();
>>    try {
>>      return broker.getCollectionByQuery(query);
>>    }
>>    catch (Exception e) {
>>      log.error("Exception in listAllAcks(): ", e);
>>      throw new Exception("Exception in listAllAcks(): ", e);
>>    }
>>    finally {
>>      broker.close();
>>    }
>>  }
>>
>>  public void addAck() throws Exception {
>>    PersistenceBroker broker = super.getDefaultBroker();
>>    try {
>>      broker.beginTransaction();
>>      broker.store(this);
>>      broker.commitTransaction();
>>    }
>>    catch (Exception e) {
>>      broker.abortTransaction();
>>      log.error("Exception in addAck(): ", e);
>>      throw new Exception("Exception in addAck(): ", e);
>>    }
>>    finally {
>>      broker.close();
>>    }
>>  }
>>
>>  public Acknowledgement selectAck() throws Exception {
>>    Query query = new QueryByCriteria(this);
>>    PersistenceBroker broker = super.getDefaultBroker();
>>    try {
>>      Acknowledgement ack = (Acknowledgement)broker.getObjectByQuery(query);
>>      return ack;
>>    }
>>    catch (Exception e) {
>>      log.error("Exception in selectAck(): ", e);
>>      throw new Exception("Exception in selectAck(): ", e);
>>    }
>>    finally {
>>      broker.close();
>>    }
>>  }
>>
>>  public void editAck() throws Exception {
>>    PersistenceBroker broker = super.getDefaultBroker();
>>    try {
>>      broker.beginTransaction();
>>      broker.store(this);
>>      broker.commitTransaction();
>>    }
>>    catch (Exception e) {
>>      broker.abortTransaction();
>>      log.error("Exception in editAck(): ", e);
>>      throw new Exception("Exception in editAck(): ", e);
>>    }
>>    finally {
>>      broker.close();
>>    }
>>  }
>>
>>  public void removeAck() throws Exception {
>>    PersistenceBroker broker = super.getDefaultBroker();
>>    try {
>>      broker.beginTransaction();
>>      broker.delete(this);
>>      broker.commitTransaction();
>>    }
>>    catch (Exception e) {
>>      broker.abortTransaction();
>>      log.error("Exception in removeAck(): ", e);
>>      throw new Exception("Exception in removeAck(): ", e);
>>    }
>>    finally {
>>      broker.close();
>>    }
>>  }
>>}
>>
>>
>>    
>>
>>------------------------------------------------------------------------
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
>>For additional commands, e-mail: ojb-user-help@db.apache.org
>>


Re: Foreign Key column not getting updated

Posted by Jason McKerr <mc...@nacse.org>.
OK, I've done some more testing.  Basically I'm finding that

a) If the foreign key datatype is a primitive (int) it works fine, but
you can't null it

OR 

b) If it's not a primitive, the reference (reference-descriptor) object
MUST exist and be set for the foreign-key to persist.  That means I have
two choices:

1) Switch to primitives
2) do runtime checks.  As in, 
	if (fkID != null) {
		Object a = new Object();
		a.setPK(fkID);
	}
broker.store(this);

Included is the Java file (attached) and the snippet from my
repository.xml.

Thanks,

Jason

----------------Snippet----------------------------------



<!-- Definitions for org.nacse.nees.data.project.Acknowledgement -->
  <class-descriptor class="org.nacse.nees.data.project.Acknowledgement"
table="ACKNOWLEDGEMENT">
    <field-descriptor name="ackID" column="ACKID" jdbc-type="INTEGER"
primarykey="true" autoincrement="true" sequence-name="ackSeq"/>
    <field-descriptor name="projectID" column="PROJECTID"
jdbc-type="INTEGER"
conversion="org.apache.ojb.broker.accesslayer.conversions.Int2IntegerFieldConversion"/>
    <field-descriptor name="acknowledgements" column="ACKNOWLEDGEMENTS"
jdbc-type="VARCHAR"/>
    <field-descriptor name="sponsors" column="SPONSORS"
jdbc-type="VARCHAR"/>
    <field-descriptor name="ackOptLock" column="ACKOPTLOCK"
jdbc-type="INTEGER" locking="true"/>
    <reference-descriptor
      name="projectRef"
      class-ref="org.nacse.nees.data.project.Project"
      auto-retrieve="false"
      auto-update="false"
      auto-delete="false">
      <foreignkey field-ref="projectID"/>
    </reference-descriptor>
  </class-descriptor>













On Wed, 2003-06-25 at 10:11, Jakob Braeuchi wrote:
> hi jason,
> 
> i'd prefer the wrappers. primitives are bad.
> could you please provide your class and repository.
> 
> jakob
> 
> Jason McKerr wrote:
> 
> >OK, looking at the repository.dtd file, it seems that reference
> >descriptors cannot be a wrapper datatype (Integer).  It must be
> >primitive.  Does that mean I can't have a nullable foreign key? I know
> >that's unusual, but it's not that unusual.
> >
> >Switching to an int made it work, but now it's required.  Is there a way
> >around this? Using a conversion?
> >
> >Jason
> >
> >
> >On Wed, 2003-06-25 at 09:20, Jason McKerr wrote:
> >  
> >
> >>Hey guys,
> >>
> >>I'm having a problem with a nullable foreign-key column not getting
> >>updated.
> >>
> >>I've got a table (Acknowledgements) that has a foreign key to the
> >>Project table.  
> >>
> >>Now if I have all of the columns set for acknowledgements (including
> >>projectID) all of the columns except projectID are getting set when I
> >>call store().  The projectID is getting set to null.
> >>
> >>If I comment out the reference call to Project from the Acknowledgement
> >>table in my repository, the column gets set normally.
> >>
> >>So the question is: Can I not just do an insert without a complete
> >>object reference?  I'm doing a lot of this over serialized XML so it's
> >>not cool to have to pass an object graph just to do an isnert on a minor
> >>related table.
> >>
> >>Jason
> >>
> >>
> >>
> >>
> >>---------------------------------------------------------------------
> >>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: Foreign Key column not getting updated

Posted by Jakob Braeuchi <jb...@gmx.ch>.
hi jason,

i'd prefer the wrappers. primitives are bad.
could you please provide your class and repository.

jakob

Jason McKerr wrote:

>OK, looking at the repository.dtd file, it seems that reference
>descriptors cannot be a wrapper datatype (Integer).  It must be
>primitive.  Does that mean I can't have a nullable foreign key? I know
>that's unusual, but it's not that unusual.
>
>Switching to an int made it work, but now it's required.  Is there a way
>around this? Using a conversion?
>
>Jason
>
>
>On Wed, 2003-06-25 at 09:20, Jason McKerr wrote:
>  
>
>>Hey guys,
>>
>>I'm having a problem with a nullable foreign-key column not getting
>>updated.
>>
>>I've got a table (Acknowledgements) that has a foreign key to the
>>Project table.  
>>
>>Now if I have all of the columns set for acknowledgements (including
>>projectID) all of the columns except projectID are getting set when I
>>call store().  The projectID is getting set to null.
>>
>>If I comment out the reference call to Project from the Acknowledgement
>>table in my repository, the column gets set normally.
>>
>>So the question is: Can I not just do an insert without a complete
>>object reference?  I'm doing a lot of this over serialized XML so it's
>>not cool to have to pass an object graph just to do an isnert on a minor
>>related table.
>>
>>Jason
>>
>>
>>
>>
>>---------------------------------------------------------------------
>>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: Foreign Key column not getting updated

Posted by Jason McKerr <mc...@nacse.org>.
OK, looking at the repository.dtd file, it seems that reference
descriptors cannot be a wrapper datatype (Integer).  It must be
primitive.  Does that mean I can't have a nullable foreign key? I know
that's unusual, but it's not that unusual.

Switching to an int made it work, but now it's required.  Is there a way
around this? Using a conversion?

Jason


On Wed, 2003-06-25 at 09:20, Jason McKerr wrote:
> Hey guys,
> 
> I'm having a problem with a nullable foreign-key column not getting
> updated.
> 
> I've got a table (Acknowledgements) that has a foreign key to the
> Project table.  
> 
> Now if I have all of the columns set for acknowledgements (including
> projectID) all of the columns except projectID are getting set when I
> call store().  The projectID is getting set to null.
> 
> If I comment out the reference call to Project from the Acknowledgement
> table in my repository, the column gets set normally.
> 
> So the question is: Can I not just do an insert without a complete
> object reference?  I'm doing a lot of this over serialized XML so it's
> not cool to have to pass an object graph just to do an isnert on a minor
> related table.
> 
> Jason
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org