-->
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.  [ 5 posts ] 
Author Message
 Post subject: Association mappings
PostPosted: Thu Nov 10, 2005 8:23 am 
Newbie

Joined: Mon Aug 08, 2005 8:33 am
Posts: 7
I am trying out the association described in 8.2.1 of the Hibernate 3 manual. I have slightly modified the mapping (see reason below).

<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</class>

<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>

<property name="fullAddress"/>

</class>

This correctly generates:
create table Address (addressId integer not null auto_increment, fullAddress var
char(255), primary key (addressId))
create table Person (personId integer not null auto_increment, name varchar(255)
, addressId integer not null, primary key (personId))
alter table Person add index FK8E48877552F0AFE3 (addressId), add constraint FK8E
48877552F0AFE3 foreign key (addressId) references Address (addressId)

This is the code that I am using to create the Person and address


Address a = new Address("Church Road London");
Address a1 = new Address("Church Road London");
Person p= new Person();
Person p1= new Person();

p.setName("James");
p.setAddress(a);
p1.setName("Bob");
p1.setAddress(a1);

s.save(p);
s.save(p1);
s.flush();

t.commit();
s.close();
t.commit();
s.close();

This works as well but I have two questions.

1. cascade

Unless I add a cascade attiibute (e.g.cascade="all") to the many to one mapping, the address is not saved. Is that right?

<many-to-one name="Address" column="addressId" cascade="all"
not-null="true"/>

2. unique fullAddress column

The code above works but it creates 2 records in the Address table.

What I really want to do is create one record in the Address table when the fullAddress is the same as the fullAddress of another row and for the addressId in the Person table to use the addressid of that previously created row.

if I change the line of code p1.setAddress(a1) to p1.setAddress(a), it correctly uses the same row because it is the same object. What I want Hibernate to do is to read the address table to see if there is a row with the same fullAddress and use the addressId of that row when saving the person row.

Is there a neat way to do this with Hibernate?


James

Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:

Mapping documents:

Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:

Name and version of the database you are using:

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 10, 2005 9:31 am 
Regular
Regular

Joined: Thu Oct 27, 2005 8:06 am
Posts: 55
Location: München, Germany
1. You can either cascade or explicitly save your addresses.

2. For Hibernate, the two different address instances are just that: two instances. They both have to be saved. Therefore, your application has to decide whether at all to instantiate a second object.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 10, 2005 9:48 am 
Newbie

Joined: Mon Aug 08, 2005 8:33 am
Posts: 7
Thomas Matzner wrote:
1. You can either cascade or explicitly save your addresses.

2. For Hibernate, the two different address instances are just that: two instances. They both have to be saved. Therefore, your application has to decide whether at all to instantiate a second object.


assuming the second object is not in menory, does this mean that I have to select an existing address from the Address table and reuse that object. Is there any other way to do it automatically via a mapping?

James?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 10, 2005 2:32 pm 
Newbie

Joined: Mon Aug 08, 2005 8:33 am
Posts: 7
jmc42 wrote:
assuming the second object is not in menory, does this mean that I have to select an existing address from the Address table and reuse that object. Is there any other way to do it automatically via a mapping?


I have stumbled a bit further.

By using a composite key:

<composite-id>
<key-property name="id" column="addressId"/>
<key-property name="fullAddress" column="fullAddress"/>
</composite-id>

I can save an address object in one session and then in another session create another address with same value for fullAddress and saveorUpdate will not create 2 rows but automatically find the existing row. Is this the right way to handle this?

The next problem is how to refer to this composite key in the Person many-to-one mapping. The composite key causes a "must have same number of columns as the referenced primary key" error. I guess that a <key-many-to-one> mapping needs to be specified.

What should the key-many-to-one and the modified many-to-one mapping look like?

<many-to-one name="address"
column="addressId"
not-null="true"/>

James


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 18, 2005 4:08 pm 
Regular
Regular

Joined: Thu Oct 27, 2005 8:06 am
Posts: 55
Location: München, Germany
Deciding whether two person objects/records of your problem domain should refer to the same address object/record of your problem domain is not a function that should be left to a technical platform like the database system or Hibernate. Solving this by application logic is (maybe) 2 LoC more than trying to invent a mapping trick, but those 2 lines will be easier to figure out than the trick -- and they will be more stable.

Imagine someone comes and requests that "Church Road London" should be interpreted as the same address as "Curch Road, London". Then all database key tricks will be useless, and you'll have to solve this little thing in your app.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

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.