-->
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.  [ 10 posts ] 
Author Message
 Post subject: Simple question
PostPosted: Tue Jun 10, 2008 5:22 am 
Newbie

Joined: Tue Jun 10, 2008 5:12 am
Posts: 6
Hello all,

I am new in hibernate and have simple question.

I have the following data model.

class Address {
int id;
Country country;
}

class Country {
int id;
String name;
}

.hbm is the following :

<class name="Country" table="Countries">
<id name="id" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<property name="name" column="name" not-null="true"/>
</class>

<class name="Address" table="Addresses">
<id name="id" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<one-to-one name="country" class="Country"/>
</class>

I load this class from database. All is OK. Then I try to modify address.
I set new country but do not change country filed just country.id. Then
I try to save modified object. There are not exceptions but my changes are not saved and just ignored.

..
int id = 1;
Address address = getAddress(id);
System.out.println(address.country.id); // pring "1"
System.out.println(address.country.name); //print "USA"
address.country.id = 2;
save(address);
...
address = getAddress(id);
System.out.println(address.country.id); // pring "1"
System.out.println(address.country.name); //print "USA"
...

I really do not want to do something like this to solve this problem :
...
Address address = getAddress(id);
address.country = getCountry(2);
save(address);
...

Could you please help me? Is is possible to automatically change country.name filed if country.id is changed?

Thanks,
Aritomo

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:


Problems with Session and transaction handling?

Read this: http://hibernate.org/42.html


Top
 Profile  
 
 Post subject: try a cascade
PostPosted: Tue Jun 10, 2008 6:09 am 
Regular
Regular

Joined: Thu Dec 22, 2005 7:47 am
Posts: 62
Location: Czech Republic
see hibernate manual:

http://www.hibernate.org/hib_docs/refer ... d-cascades

this will enable you to:

Code:
Address a = getAddress(1);
Country c = getCountry(2);
a.setCountry(c);
save(a); // if cascade is set and address is a parent to country, this will issue required update


you may try to set hibernate to show sql queries (again, see manual), to see what is going on behind the scenes.

imho it is very strange to do:

a.country.id = <something>

you need to set the refernce of object a to reference another object c -- the most obvious way is to use (if you do not want getters/setters) a.country = c;

doing a.country.id = 2 means you are trying to change the primary key of the existing object a.country, you _do_not_ change the reference of a to another object.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 6:55 am 
Newbie

Joined: Tue Jun 10, 2008 5:12 am
Posts: 6
Thanks a lot.

Now I modify reference as you proposed.

<class name="Country" table="Countries">
<id name="id" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<property name="name" column="name" not-null="true"/>
</class>

<class name="Address" table="Addresses">
<id name="id" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<one-to-one name="country" class="Country" cascade="all"/>
</class>

But changes does not affect address.

id = 1;
Address address = getAddress(id);
address.country = getCountry(2);
save(address);
address = getAddress(id);
System.out.println(address.country.id); // pring "1"
System.out.println(address.country.name); //print "USA"

Could you please help me?

Thanks,
Aritomo


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 8:15 am 
Regular
Regular

Joined: Thu Dec 22, 2005 7:47 am
Posts: 62
Location: Czech Republic
please, enable query logging, for example if you are using hibernate.xml config, add the following (for properties file just use the property names as keys, keep the values the same:

Code:
    <property name="hibernate.show_sql">false</property>
    <property name="hibernate.format_sql">true</property>


Code:
save(address);
session.flush();


and set the output here, you should see the queries to be executed.[/code]


Top
 Profile  
 
 Post subject: Log
PostPosted: Tue Jun 10, 2008 8:37 am 
Newbie

Joined: Tue Jun 10, 2008 5:12 am
Posts: 6
Log is the following :
update Addresses set StreetNumber=? where id=?
update Countries set name=? where id=?

StreetNumber is just string field. But why country field is not updated?

Thanks,
Aritomo


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 9:16 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Code:
Address a = getAddress(1);
Country c = getCountry(2);
a.setCountry(c);
save(a);


This code will update the country the address object is associated with, but it will not effect the country itself, only the country the address instance is associated with.

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject: Still have problems
PostPosted: Tue Jun 10, 2008 9:32 am 
Newbie

Joined: Tue Jun 10, 2008 5:12 am
Posts: 6
I am sorry. But I still have problem.

Let's me explain :

I have Countries table

table Countries {
int id;
int name;
}

that has e.g. two entries
Countries.id = 1
Countries.name = 'USA'

Countries.id = 2
Countries.name = 'Japan'

Also I have Addresses table :

table Addresses {
int id;
int countryId;
}


Also I have JavaBeans

class Country {
int id;
String name;
}

class Address {
int id;
Country country;
}

I develop .hbm :

<hibernate-mapping>
<class name="Country" table="Countries">
<id name="id" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<property name="name" column="name" not-null="true"/>
</class>
<class name="Address" table="Addresses">
<id name="id" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<???-to-??? name="country" class="Country" column="countryId" />
</many-to-one>
</class>
</hibernate-mapping>

Which association should I use here? many-to-one or one-to-one or something else ?

Could you please give me example?

Also I have the following data in Addresses table
Addresses.id = 1
Addresses.countryId=1

Addresses.id = 2
Addresses.countryId=2

Addresses.id = 1
Addresses.countryId=2

Thanks,
Aritomo


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 9:38 am 
Regular
Regular

Joined: Thu Dec 22, 2005 7:47 am
Posts: 62
Location: Czech Republic
for simple reference, use many-to-one from child to parent.

i guess there is only one USA and Japan, but there is several addresses in either country.

you want just one country for every country in the world. you want several addresses in each country.

so:

Address: Washington, ... -> Country USA
Address: New Jersey, ... -> Country USA
Address: Tokyo, ... -> Japan

so use many-to-one in Address.hbm.xml

But this problem have very little common with hibernate -- this is more of a database design, you should read something about SQL databases.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 10:31 am 
Newbie

Joined: Tue Jun 10, 2008 5:12 am
Posts: 6
Thanks a lot for help,

Now I use many-to-one :

<hibernate-mapping>
<class name="Country" table="Countries">
<id name="id" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<property name="name" column="name" not-null="true"/>
</class>
<class name="Address" table="Addresses">
<id name="id" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<many-to-one name="country" class="Country" column="countryId" />
</many-to-one>
</class>
</hibernate-mapping>

countryId is loaded successfully but name of country is null (Country.name) .
I thinked that name should be loaded automatically? Am I mistaken? Where is error?

Please help.

Thanks,
Aritomo


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 11:26 am 
Regular
Regular

Joined: Thu Dec 22, 2005 7:47 am
Posts: 62
Location: Czech Republic
i guess, you should use getters and setters. ie country.getName() instead of simple country.name

1. by default (your hbm does not specify otherwise) you have always have proxies for associations (like Address -> Country) (ie. properties are null)

2. by default (your hbm does not specify otherwise) as default access method there is a getters/setters, no direct access (ie. the proxy loads the object state (attributes) ones you call a getter/setter)

You hav etoo options:

1. (preferred) define getters/setters

2. define another access method ('field') -- see http://www.hibernate.org/hib_docs/refer ... eclaration and search for "access"


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 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.