-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: one-to-one mapping
PostPosted: Fri Mar 17, 2006 7:58 pm 
Beginner
Beginner

Joined: Fri Mar 17, 2006 7:30 pm
Posts: 32
I cannot believe that this is so difficult to do in H3. This is so simple in ATG's Dynamo that it is laughable I can't solve this in H3. I have a main table like so:

User_info
------------
user_id
first_name
Last_name

And an additional table holding extra "user information"

Opt_ins
-------------
optin_id
user_id
newsletter
quarterly_mailings

The Pojo UserInfo contains a property for OptIns.

Mapping as such:

<class name="OptInsBean" table="Opt_ins">
<cache usage="read-write" region="registrationCache"/>
<id name="optInId" type="string" column="OPTIN_ID">
<generator class="sequence">
<param name="sequence">REG_OI_ID_SEQ</param>
</generator>
</id>
<property name="userId" type="string" column="USER_ID"/>
<property name="newsletter" type="string" column="NEWSLETTER"/>
<property name="quarterlyMailings" type="string" column="quarterly_mailings"/>
</class>

and for the optIn property for User_info:

<one-to-one name="optIns" class="OptInsBean" constrained="false" property-ref="userId" foreign-key="USER_ID" lazy="false"/>

No error is thrown, but when a new user is inserted into the database, no data ever goes into the opt in table. What am I missing here?

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 17, 2006 8:59 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
setup your
<property name="userId" type="string" column="USER_ID"/>
to be of type "User_info" not by key. (fully qualified package.class name in the type.


The OptInsBean class
would have a member variable declared as such:
User_info user=null;


Hope that helps

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 17, 2006 10:05 pm 
Beginner
Beginner

Joined: Fri Mar 17, 2006 7:30 pm
Posts: 32
jt_1000 wrote:
setup your
<property name="userId" type="string" column="USER_ID"/>
to be of type "User_info" not by key. (fully qualified package.class name in the type.


The OptInsBean class
would have a member variable declared as such:
User_info user=null;


Hope that helps


I have to put UserInfoBean data into the OptInsBean? Why?

If this is the case, then I might as well place saving and loading logic in the User manager and do the optins property as a separate operation.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 17, 2006 10:46 pm 
Beginner
Beginner

Joined: Fri Mar 17, 2006 7:30 pm
Posts: 32
jt_1000 wrote:
setup your
<property name="userId" type="string" column="USER_ID"/>
to be of type "User_info" not by key. (fully qualified package.class name in the type.


The OptInsBean class
would have a member variable declared as such:
User_info user=null;


Hope that helps


I tried this and it not work. It did make for a lovely stack trace during server start up though.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 17, 2006 11:44 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
Here is a sample of one-to-one with Person and Car

I hope it helps!


Car class mapping
Code:
<hibernate-mapping>
    <class
        name="samples_0.Car"
        table="SAMPLE0_CAR"
    >

        <id
            name="CAR_ID"
            column="CAR_ID"
            type="java.lang.Long"
            unsaved-value="null"
        >
            <generator class="hilo">
                <param name="table">SAMPLE0_CAR_SEQ</param>
                <param name="column">NEXT</param>
              <!--
                  To add non XDoclet generator parameters, create a file named
                  hibernate-generator-params-Person.xml
                  containing the additional parameters and place it in your merge dir.
              -->
            </generator>
        </id>

        <property
            name="CAR_NAME"
            update="true"
            insert="true"
            not-null="false"
            unique="false"
            type="defaultString"
        >
            <column name="CAR_NAME" default="n/a"/>
        </property>

        <many-to-one
            name="person"
            class="samples_0.Person"
            cascade="all"
            column="PERSON_ID"
            unique="true"
        />

    </class>
</hibernate-mapping>


Car java code:
Code:
public class Car
{
    Person person=null;
    Long CAR_ID=null;
    String CAR_NAME="";
    ...with getters and setters foreach attribute defined.
}


Person Class mapping.
Code:
<hibernate-mapping
>
    <typedef class="java.lang.String" name="defaultString">
        <param name="default">n/a</param>
    </typedef>
    <class
        name="samples_0.Person"
        table="SAMPLE0_Person"
    >

        <id
            name="PERSON_ID"
            column="PERSON_ID"
            type="java.lang.Long"
            unsaved-value="null"
        >
            <generator class="hilo">
                <param name="table">SAMPLE0_PERSON_SEQ</param>
                <param name="column">NEXT</param>
              <!--
                  To add non XDoclet generator parameters, create a file named
                  hibernate-generator-params-Person.xml
                  containing the additional parameters and place it in your merge dir.
              -->
            </generator>
        </id>

        <property
            name="FIRST_NAME"
            update="true"
            insert="true"
            not-null="false"
            unique="false"
            type="defaultString"
        >
            <column name="FIRST_NAME" default="n/a"/>
        </property>

        <property
            name="LAST_NAME"
            type="java.lang.String"
            update="true"
            insert="true"
            column="LAST_NAME"
            not-null="true"
            unique="false"
        />
        <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
    </class>
</hibernate-mapping>



Person java code:
Code:
public class Person
{
    Long PERSON_ID=null;
    String FIRST_NAME=null;
    String LAST_NAME=null;
    ...with getters and setters foreach attribute defined.
}


Calling Java code:
Code:
Person p1 = new Person();
p1.setFIRST_NAME("JEFF");
p1.setLAST_NAME("JOHnson");
Car c=new Car();
c.setCAR_NAME("BMW");
c.setPerson(p1);
sess.saveOrUpdate(c);

tx.commit();

System.out.println("c.getPerson().getPERSON_ID() = " + c.getPerson().getPERSON_ID());
System.out.println("p1.getPERSON_ID() = " + p1.getPERSON_ID());


SQL code:

Code:
drop table SAMPLE0_PERSON;
drop table SAMPLE0_PERSON_SEQ;
create table SAMPLE0_PERSON
(
    PERSON_ID number primary key,
    FIRST_NAME varchar2(64),
    LAST_NAME varchar2(64),
    created timestamp default systimestamp
);
create table SAMPLE0_PERSON_SEQ
(
   NEXT number default 0
);
insert into SAMPLE0_person_seq values(1);
commit;

-- for the one-to-one relationship
create table SAMPLE0_CAR_SEQ
(
   NEXT number default 0
);
insert into SAMPLE0_CAR_SEQ values(1);
commit;

drop table SAMPLE0_CAR;
create table SAMPLE0_CAR
(
CAR_ID number primary key,
CAR_NAME varchar2(256),
PERSON_ID number
);
alter table sample0_car add constraint fk_car_person foreign key (person_id)
references sample0_person(person_id);

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 18, 2006 12:58 am 
Beginner
Beginner

Joined: Fri Mar 17, 2006 7:30 pm
Posts: 32
So, both Car and Person have to know about each other? That totally defeats the purpose of the relationship. That is very sad. I knew Hibernate was light weight, but that is anorexic. Or am I still missing something?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 18, 2006 8:57 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
only the car knows about the person in my example.

going back to my first comment... you were trying to associate them by storing the ID, not the object reference. The example, should help you to see what I was taking about.. since the Car has a Person attribute and the <many-to-one with unique allows me to map by another PK besides CAR_ID.... if I was simply mapping by the same key in both Entities, I'd use a <one-to-one....> Also I could have a bi-directional relationship by putting some tags in the Person and providing a Car attribute in the Person class, if I wanted...

Hope this clears it up a little?

check out:
[url]http://www.hibernate.org/hib_docs/v3/reference/en/pdf/hibernate_reference.pdf
[/url]
page 61 for more info.

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 18, 2006 10:33 pm 
Beginner
Beginner

Joined: Fri Mar 17, 2006 7:30 pm
Posts: 32
jt_1000 wrote:
only the car knows about the person in my example.

going back to my first comment... you were trying to associate them by storing the ID, not the object reference. The example, should help you to see what I was taking about.. since the Car has a Person attribute and the <many-to-one with unique allows me to map by another PK besides CAR_ID.... if I was simply mapping by the same key in both Entities, I'd use a <one-to-one....> Also I could have a bi-directional relationship by putting some tags in the Person and providing a Car attribute in the Person class, if I wanted...

Hope this clears it up a little?

check out:
[url]http://www.hibernate.org/hib_docs/v3/reference/en/pdf/hibernate_reference.pdf
[/url]
page 61 for more info.


I fail to see what page 61 has to do with my problem.

As to your example, yes it does clear it up. It tells me that Hibernate is officially 7 years behind ATG's Repository framework. You have the relationships backwards from my problem. In order to do it the Hibernate way, I have to either place a FK column in the user_info table or place the User object in the OptIn object. This is goofy and breaks the relationship completely. The Opt_in table contains extra attributes about a user and should therefore be stored in the user object. Adding a column to the User_info table is not an option.

I still find it very hard to believe that Hibernate claims to be a moderm O/R map, yet it can't handle one of the most basic relationships databases have. I still think I am missing something, but I am slowly starting to belive that I am not.

Since this is something that MUST go live on Monday, I have placed the saving of the optins in the user manager when it saves a new user. Currently, the extended attributes are not read by other parts of the application, so I have not added a read support yet. I will also need to make note of the programming requirements should more attributes get added to the user in the registration process in the future. I never realized how spoiled I was with the ATG server. Now I know.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 18, 2006 10:41 pm 
Beginner
Beginner

Joined: Fri Mar 17, 2006 7:30 pm
Posts: 32
jt_1000 wrote:
only the car knows about the person in my example.


Though your replies have not solved my problem, I have marked them as helpful so you will get credit for your efforts. Unless you can change your example to have the car object in the Person object, without making any databases changes (like car id in the person table), then I guess what I need to do just can't be done. What makes me the saddest is two things. The time I spent trying to configure H3 and that I wrote a VERY ligth wieght O/R mapping framework for .Net a year ago for a project and it handled this easily.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 19, 2006 3:57 am 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
in my example if you add to the Person mapping:

<one-to-one name="car" class="samples_0.Car" property-ref="person" cascade="all" />

the property-ref person refers to the person attribute of the Car class.
cascade="all" tells hibernate to cascade the insert/update operations to the Car class.


And then in your Java code:

Person p1 = new Person();
p1.setFIRST_NAME("Betty");
p1.setLAST_NAME("Johnson");
Car c=new Car();
c.setCAR_NAME("Celica");
p1.setCar(c);
c.setPerson(p1);
sess.saveOrUpdate(p1);
tx.commit();

This way I am saving from the Person side only.

Does that help? This addresses your concern about not moving the ID to the other table..

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 19, 2006 12:51 pm 
Beginner
Beginner

Joined: Fri Mar 17, 2006 7:30 pm
Posts: 32
jt_1000 wrote:
in my example if you add to the Person mapping:

<one-to-one name="car" class="samples_0.Car" property-ref="person" cascade="all" />

the property-ref person refers to the person attribute of the Car class.
cascade="all" tells hibernate to cascade the insert/update operations to the Car class.


And then in your Java code:

Person p1 = new Person();
p1.setFIRST_NAME("Betty");
p1.setLAST_NAME("Johnson");
Car c=new Car();
c.setCAR_NAME("Celica");
p1.setCar(c);
c.setPerson(p1);
sess.saveOrUpdate(p1);
tx.commit();

This way I am saving from the Person side only.

Does that help? This addresses your concern about not moving the ID to the other table..


Actually, it does. It shows what I stated earlier in that both objects must contain each other. In my case, the Optins need to have a User object in the POJO instead of the user id. I find this very nutty, but I guess it is a requirement that I will have to learn to deal with. The easiest solution here would have been for H3 to support the creation of the Optin object in the User object by the user_id FK in the optin table. Why is it that H3 does not support such a simple relationship and operation?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 19, 2006 1:06 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
I agree. Seems fairly complicated. It would be much simpler if it was built into the <one-to-one tags somehow on both side, but that seems (according to the docs and some testing on my part) to be limited to using the same key on both ends... and if you want the flexibility to specify the one-to-one relationship other FK, then you have to use the <many-to-one>... and when using the <many-to-one you have to embed the FK on the "many" side of things...(that part is just relational theory). I think where hibernate deviated from proper design is stating that one should use the "many-to-one w/ unique" to allow for "other" key (as mentioned above). It reuses the semantics of <many-to-one for another concept of <one-to-one>...

It would have been better to just have designed hibernate to accept the proper FK in the <one-to-one>... perhaps the foreign-key, but that apparently (not known for sure on my part) only works for DDL generation to specify the proper FK constraints... (some times, I admit I just go with what I know works, and don't question...whys/wherefores..etc.).

This is why I was refering you to the docs.

Perhaps if some of the Hib team members are listening they can chime in and correct or confirm my analysis... ;)

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 19, 2006 6:11 pm 
Beginner
Beginner

Joined: Fri Mar 17, 2006 7:30 pm
Posts: 32
jt_1000 wrote:
I agree. Seems fairly complicated. It would be much simpler if it was built into the <one-to-one tags somehow on both side, but that seems (according to the docs and some testing on my part) to be limited to using the same key on both ends... and if you want the flexibility to specify the one-to-one relationship other FK, then you have to use the <many-to-one>... and when using the <many-to-one you have to embed the FK on the "many" side of things...(that part is just relational theory). I think where hibernate deviated from proper design is stating that one should use the "many-to-one w/ unique" to allow for "other" key (as mentioned above). It reuses the semantics of <many-to-one for another concept of <one-to-one>...

It would have been better to just have designed hibernate to accept the proper FK in the <one-to-one>... perhaps the foreign-key, but that apparently (not known for sure on my part) only works for DDL generation to specify the proper FK constraints... (some times, I admit I just go with what I know works, and don't question...whys/wherefores..etc.).

This is why I was refering you to the docs.

Perhaps if some of the Hib team members are listening they can chime in and correct or confirm my analysis... ;)


I do agree with you that the double use of the many-to-one tag is bad design and leads to errors. A reverse direction on the one-to-one tag makes more sense.


Top
 Profile  
 
 Post subject: Just one small doubt about Car-Person mapping
PostPosted: Mon Mar 20, 2006 2:39 am 
Newbie

Joined: Thu Mar 16, 2006 5:43 am
Posts: 5
Location: Delhi, India
From this post, I got big understanding and help in mapping my one-to-one relationship for my sample application. Finally I was able to get the things going but one doubt remains in my mind, hence I am putting up a reply to actually ask a question. My apologies...
Question is in the same Person and Car context. Is it anyways possible to avoid the many-to-one mapping on the car side, whichever way map the objects either in reverse Car-Person many-to-one relation or forward Person-Car one-to-one relation? I want to put up realtional mapping code only on one side, is that possible.
My code with one-to-one relation set up in Person side (Person.hbm.xml), does not work if I put remove the car side (car.hbm.xml) many-to-one relation and set the Car class property "person" as a simple property like

<property name="person" type="package.Person" />

If I replace the above code in car.hbm.xml by

<many-to-one name="person" class="package.Person" cascade="all" column="PERSON_ID" unique="true" />

it works well with one-to-one mapped on Person side. Is it feasible to get away with many-to-one relation on Car side???

_________________
Thanks and Regards,
Cpt. Blue Streak
_______________________________________


Top
 Profile  
 
 Post subject: Re: Just one small doubt about Car-Person mapping
PostPosted: Mon Mar 20, 2006 8:33 am 
Beginner
Beginner

Joined: Fri Mar 17, 2006 7:30 pm
Posts: 32
BlueStreak wrote:
From this post, I got big understanding and help in mapping my one-to-one relationship for my sample application. Finally I was able to get the things going but one doubt remains in my mind, hence I am putting up a reply to actually ask a question. My apologies...
Question is in the same Person and Car context. Is it anyways possible to avoid the many-to-one mapping on the car side, whichever way map the objects either in reverse Car-Person many-to-one relation or forward Person-Car one-to-one relation? I want to put up realtional mapping code only on one side, is that possible.
My code with one-to-one relation set up in Person side (Person.hbm.xml), does not work if I put remove the car side (car.hbm.xml) many-to-one relation and set the Car class property "person" as a simple property like

<property name="person" type="package.Person" />

If I replace the above code in car.hbm.xml by

<many-to-one name="person" class="package.Person" cascade="all" column="PERSON_ID" unique="true" />

it works well with one-to-one mapped on Person side. Is it feasible to get away with many-to-one relation on Car side???


Based on what I've learned over the course of this, that would not be possible.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.