Re: How can I handle 1:1 relationships?

Iris Soto <[email protected]>
Newsgroups gmane.comp.jakarta.ojb.user
Message-ID <[email protected]>
Armin Waibel escribió:
> Hi Iris,
>
> I implemented your test and run against latest from SVN 
> (OJB_1_0_RELEASE branch, upcoming OJB 1.0.5).
>
> The test can be found here:
> http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/OneToOneWithoutFKTest.java?view=markup 
>
> The mapping here (end of file):
> http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/repository_junit_reference.xml?view=markup 
>
>
> When using proxied references I can reproduce your NPE. The reason for 
> the NPE I described in my previous post:
> <snip>
> In your mapping you don't use separate FK for the 1:1 references. This 
> could cause unexpected behavior when using proxy references. Assume 
> you are nullify the Passport of a Person. Next time you materialize 
> the Person object OJB tries to resolve the reference to Passport by 
> lookup the FK defined in Person. You define the Person PK as FK for 
> Passport reference (the FK to Passport could never be nullified), thus 
> OJB assume that the reference to Passport still exists and create a 
> proxy reference (instead of setting null). If you now try to access 
> the Passport reference in Person you will get a NPE, because OJB can't 
> find the Passport object.
> </snip>
> I don't know how we can prevent the proxy object creation without 
> database access (this will kill performance). Currently I fixed it by 
> returning 'null' for all proxied methods of the "not existing reference".
>
> regards,
> Armin
>
>
> Iris Soto wrote:
>> Armin Waibel escribió:
>>> Iris Soto wrote:
>>>> Hello Armin, thanks for ask me,
>>>> the version of OJB that i'm using is y.IndirectionHandler -1.0.4, 
>>>> in the OJB.properties file i  have enable CGLib proxy support. I 
>>>> has been try test pass without using proxied references, and there 
>>>> is nothing different, the error is the same. I want to make 
>>>> bidirectional reference even though the passport is null when make 
>>>> reference in person
>>>> to passport. OJB can work with this null reference?
>>>>
>>>
>>> I currently try to write a test to reproduce your problem. Could you 
>>> post some example/pseudo code to reproduce your problem?
>>>
>>> regards,
>>> Armin
>>>
>>>> Now I have:
>>>>
>>>> ****************************************************************
>>>> <class-descriptor class="org.apache.ojb.Person" table="PERSON">
>>>>       <field-descriptor name="personId" primarykey="true" 
>>>> nullable="false" autoincrement="true"... column="PERSON_ID" 
>>>> jdbc-type="INTEGER"/>
>>>>     <field-descriptor name="personName" nullable="false" 
>>>> default-fetch="true" column="PERSON_NAME" jdbc-type="VARCHAR"/>
>>>>       <reference-descriptor name="personIdRef" 
>>>> class-ref="org.apache.ojb.Passport" auto-update="true" 
>>>> auto-delete="true">
>>>>         <foreignkey field-ref="personId"/>
>>>>       </reference-descriptor>
>>>> </class-descriptor>
>>>> ****************************************************************
>>>> <class-descriptor class="org.apache.ojb.Passport" table="PASSPORT">
>>>>     <field-descriptor name="personId" primarykey="true" 
>>>> nullable="false" column="PERSON_ID" jdbc-type="INTEGER"/>
>>>>     <field-descriptor name="passport_number" nullable="false" 
>>>> default-fetch="true" column="PASSPORT_NUMBER" jdbc-type="VARCHAR"/>
>>>>     <reference-descriptor name="personIdRef" 
>>>> class-ref="org.apache.ojb.Person" auto-update="false" 
>>>> auto-delete="false">
>>>>         <foreignkey field-ref="personId"/>
>>>>       </reference-descriptor>
>>>>   </class-descriptor>
>>>>
>>>> -- 
>>>> Iris Soto
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: [email protected]
>>>> For additional commands, e-mail: [email protected]
>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [email protected]
>>> For additional commands, e-mail: [email protected]
>>>
>> To begin i need to store the person, in the test file:
>> ------------------------------------------------------------------------------------------------------- 
>>
>>    public class TestPerson extends PBTestBase {
>>        private PersonHandler personHandler;
>>        public void setUp() throws Exception {
>>            super.setUp();            personHandler = new 
>> PersonHandler();                  }
>>             public void testInsertRetrieveBroker() throws Exception {
>>            PersonHandler personHandler = new PersonHandler();
>>            Person person = new Person();
>>            person.setPersonName("Name 1");
>>             // Save to bean
>>             personHandler.insert(person);
>>             // Retrieve the bean
>>            Person personRetrieve = 
>> PersonHandler.retrieve(person.getPersonId());
>>
>>            // Remove the bean
>>            personHandler.remove(personRetrieve.getPersonId()); // 
>> Here I got the error.
>>        }
>>        protected void cleanUpDB() throws Exception {
>>            removeAll(Person.class);
>>        }
>> }
>> ---------------------------------------------------------------------------------------------------------- 
>>
>> I insert my bean call to file PersonHandler.java that contains the 
>> following:
>>
>> import org.apache.ojb.Person;
>> import org.apache.ojb.Passport;
>>
>> public class PersonHandler {
>>   /********************/
>>    public void insert(Person bean) throws Exception {
>>        PersistenceBroker broker = null;
>>
>>        try {
>>            broker = PersistenceBrokerFactory.defaultPersistenceBroker();
>>            broker.beginTransaction();                     
>> broker.store(bean);
>>            broker.commitTransaction();
>>        } catch (Exception e) {
>>            throw e;
>>        } finally {
>>            if (broker != null && !broker.isClosed()) {
>>                if (broker.isInTransaction()) {
>>                    broker.abortTransaction();
>>                }
>>                broker.close();
>>    }
>>   /********************/
>>    public void update(Person bean) throws Exception {
>>        PersistenceBroker broker = null;
>>        try {
>>            broker = PersistenceBrokerFactory.defaultPersistenceBroker();
>>            broker.beginTransaction();
>>            broker.store(bean);
>>            broker.commitTransaction();
>>            broker.clearCache();
>>        } catch (Exception e) {
>>            throw e;
>>        } finally {
>>            if (broker != null && !broker.isClosed()) {
>>                if (broker.isInTransaction()) {
>>                    broker.abortTransaction();
>>                }
>>                broker.close();
>>            }
>>        }
>>    }
>>    /**********************************/
>>    public void remove(Integer personId) throws Exception {
>>        PersistenceBroker broker = null;
>>
>>        try {
>>            broker = PersistenceBrokerFactory.defaultPersistenceBroker();
>>            broker.beginTransaction();
>>            Person bean = retrieve(personId, broker);
>>            broker.delete(bean);
>>            broker.commitTransaction();
>>            broker.clearCache();
>>        } catch (Exception e) {
>>            throw e;
>>        } finally {
>>            if (broker != null && !broker.isClosed()) {
>>                if (broker.isInTransaction()) {
>>                    broker.abortTransaction();
>>                }
>>                broker.close();
>>            }
>>        }
>>    }
>>    /****************************/
>>     public static Person retrieve(Integer personId, PersistenceBroker 
>> broker) {
>>        Person criterio = new Person();
>>        criterio.setPersonId(personId);
>>        Query query = new QueryByIdentity(criterio);
>>        return (Person) broker.getObjectByQuery(query);
>>    }
>> }
>> **************************************************************
>> Passport.java
>> ---------------------------------
>> public class Passport implements java.io.Serializable
>> {
>>   private Integer    personId;
>>   private Integer     passportNumber;
>>
>>   public Integer getPersonId() { return personId; }
>>
>>   public void setPersonId(Integer personId)
>>   {
>>      this.personId = personId;
>>   }
>>
>>   
>> //--------------------------------------------------------------------------- 
>>
>>
>>   public Integer getPassportNumber() { return passportNumber; }
>>
>>   public void setPassportNumber(Integer passportNumber)
>>   {
>>      this.passportNumber = passportNumber;
>>   }
>>
>>    
>> //--------------------------------------------------------------------------- 
>>
>>
>>   private Person PersonIdRef;
>>
>>   public Person getPersonIdRef() { return personIdRef; }
>>
>>   public void setPersonIdRef(Persons person)
>>   {
>>      this.personIdRef = person;
>>   }
>> }
>> *******************************************
>> Person.java
>> -----------------------------
>> public class Person implements java.io.Serializable
>> {
>>    public Integer getPersonId() { return PersonId; }
>>
>>   public void setPersonId(Integer PersonId)
>>   {
>>      this.PersonId = PersonId;
>>   }    
>> //--------------------------------------------------------------------------- 
>>
>>
>>   public String getPersonName() { return personName; }
>>
>>   public void setPersonName(String personName)
>>   {
>>      this.personName = personName;
>>   }
>>    
>> //--------------------------------------------------------------------------- 
>>
>>  
>>  private Passport personIdRef;
>>
>>   public Passport getPersonIdRef() { return personIdRef; }
>>
>>   public void setPersonIdRef(Passport passport)
>>   {
>>      this.personIdRef = passport;
>>   }
>> }
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
Many thanks for your help,  the process that i have is handled of 
Passport to Person, It work fine, but now
i will implement the relationship 1:1.

By the moment this is what i'm doing:
<class-descriptor class="org.apache.ojb.Person" table="PERSON">
      <field-descriptor name="personId" primarykey="true" 
nullable="false" autoincrement="true"... column="PERSON_ID" 
jdbc-type="INTEGER"/>
    <field-descriptor name="personName" nullable="false" 
default-fetch="true" column="PERSON_NAME" jdbc-type="VARCHAR"/>    
</class-descriptor>
****************************************************************
<class-descriptor class="org.apache.ojb.Passport" table="PASSPORT">
    <field-descriptor name="personId" primarykey="true" nullable="false" 
column="PERSON_ID" jdbc-type="INTEGER"/>
    <field-descriptor name="passport_number" nullable="false" 
default-fetch="true" column="PASSPORT_NUMBER" jdbc-type="VARCHAR"/>
    <reference-descriptor name="personIdRef" 
class-ref="org.apache.ojb.Person" auto-update="false" auto-delete="false">
        <foreignkey field-ref="personId"/>
      </reference-descriptor>
  </class-descriptor>

But I'm manipuling the insert and update proccess to class Passport 
manually, i mean i insert the object Passport creating the new object 
and setting personId of the class Person in the respective field of the 
class Passport, and so on,  this way it's working but is not the best, 
so I'll update to OJB 1.0.5.

Thanks you very much for your help and time gived to this problem.

-- 
Iris Soto
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.