Meaningless Drivel is fun!*
The moose likes Object Relational Mapping and the fly likes cascading classes and tables (how to update ?) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "cascading classes and tables (how to update ?)" Watch "cascading classes and tables (how to update ?)" New topic
Author

cascading classes and tables (how to update ?)

ben oliver
Ranch Hand

Joined: Mar 28, 2006
Posts: 374
I posted a thread a few days ago. My classes look like --

class LEVEL_1 {

LEVEL_2 level_2; // assume there is a Arraylist of LEVEL_2
String tour_name;
double price;
....
}

class LEVEL_2 {
LEVEL_3 level_3; // assume there is an arraylist of LEVEL_3
String flight_name;
double d;
....
}

class LEVEL_3 {
Date departure ;
Date arrival ;
....
}

My Database (MySQL) is like

Table LEVEL_1 { ID not null primary key AUTO_INCREAMENT,
tour_name varchar(30), ...}

Table LEVEL_2 { ID not null primary key AUTO_INCREAMENT,
LEVEL_1_ID int; // foreign key
flight_name varchar(30), ... }

Table LEVEL_3 { ID not null primary key AUTO_INCREAMENT,
LEVEL_2_ID int, // foreign key
departure varchar(30), ... }

i.e. each Table has its own primary key which is the unique MySQL number, and each table has a foreign key refers to another one. Assume it is one-to-many relations among tables, i.e LEVEL_1 has "many" LEVEL_2, and so on.

Now, suppose I have created Object instances of Level_1 which contains LEVEL_2, which in turn contains object of LEVEL_3, if I do a "session.save(level_1)" ---

1. will tables of "LEVEL_2" and "LEVEL_3" be updated as well ??
2. if the answer is yes, does that mean that for a new row in Table LEVEL_1, database creates a new "ID" and then "pass" this ID to "LEVEL_2" table , and then also creates a new ID for "LEVEL_2" table, and then pass that "LEVEL_2"'s ID on to "LEVEL_3", and also creates a new ID for "LEVEL_3" ?? I doubt Hibernate is so smart..
pascal betz
Ranch Hand

Joined: Jun 19, 2001
Posts: 547
have you tried ?

pascal
ben oliver
Ranch Hand

Joined: Mar 28, 2006
Posts: 374
Originally posted by pascal betz:
have you tried ?

pascal


I want to know if Hibernate can handle such scenario, not necessarily for this case. I want to know if there is any restriction/limit for such cases. If I just try this concrete scenario and find it doesn't work, it does NOT mean it can't work --- Maybe it is because I am a newbie and I don't know the right way to do it. That's why I posted that thread. If I tried and found it work, but maybe there is some restriction that i don't know, and I want to know that from expert -- that's another reason I posted that thread.

I was NOT asking anybody to try for me. I was trying to see if anybody can provide answer from conceptual level.
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2921
    
    5
Originally posted by ben oliver:
I posted a thread a few days ago. My classes look like --
1. will tables of "LEVEL_2" and "LEVEL_3" be updated as well ??
2. if the answer is yes, does that mean that for a new row in Table LEVEL_1, database creates a new "ID" and then "pass" this ID to "LEVEL_2" table , and then also creates a new ID for "LEVEL_2" table, and then pass that "LEVEL_2"'s ID on to "LEVEL_3", and also creates a new ID for "LEVEL_3" ?? I doubt Hibernate is so smart..


And your doubt is based on? Hibernate can handle it. The success hinges on whether you define the mappings properly (mainly the cascade attribute on the various mapping elements; but the are other attributes related to cascading behavior). See for example:
5.1.10. many-to-one
5.1.11. one-to-one
5.1.22. any
6.2. Collection mappings
10.11. Transitive persistence

Again - get Hibernate In Action (Hibernate In Action (ThoutReader + PDF ebook)) and read it. It discusses all these issues in detail. Hibernate doesn't cost anything so you might as well invest some time and money into the book.
ben oliver
Ranch Hand

Joined: Mar 28, 2006
Posts: 374
Originally posted by Peer Reynders:


And your doubt is based on? Hibernate can handle it. The success hinges on whether you define the mappings properly (mainly the cascade attribute on the various mapping elements; but the are other attributes related to cascading behavior). See for example:
5.1.10. many-to-one
5.1.11. one-to-one
5.1.22. any
6.2. Collection mappings
10.11. Transitive persistence

Again - get Hibernate In Action (Hibernate In Action (ThoutReader + PDF ebook)) and read it. It discusses all these issues in detail. Hibernate doesn't cost anything so you might as well invest some time and money into the book.



Thanks. And it doesn't matter if the primary or foreign key connecting the tables is a system generated unique ID or some natural key (natural business field of table), right ?
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2921
    
    5
Originally posted by ben oliver:
And it doesn't matter if the primary or foreign key connecting the tables is a system generated unique ID or some natural key (natural business field of table), right ?


There is a strong recommendation and preference towards the use of synthetic/surrogate keys. In many situations there may be a reason for the business domain (natural) key to change during the lifetime of the record/object - that does not happen for surrogate keys. The primary key of a record can never change during the lifetime of the record.
ben oliver
Ranch Hand

Joined: Mar 28, 2006
Posts: 374
Originally posted by Peer Reynders:


There is a strong recommendation and preference towards the use of synthetic/surrogate keys. In many situations there may be a reason for the business domain (natural) key to change during the lifetime of the record/object - that does not happen for surrogate keys. The primary key of a record can never change during the lifetime of the record.


Thanks lot. I feel I am very close to understanding it but still not that comfortable... Suppose we consider the above cascading class example, if in the beginning my database tables are empty and I rely on using the Object Instances of "LEVEL_1/2/3" to populate the database tables, i.e. I create those objects and insert their values into table. When I create the objects there is NO surrogate key/id involved, they are just POJOs. Then when I do ".save(level_1)" to save LEVEL_1 object into database, Hibernate will not only populate the tables but also create the unique surrogate keys and even carries the keys in a cascading way. Right ? In other words, if I have the POJOs ready, I do NOT need to do anything like "insert into ...(ID, v1, v2,..)".

Second question, if I do "insert into ..." then how can I create that surrogate key (assume I use oracle) ?

I appreciate your patience.
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2921
    
    5
First you have to set up the appropriate sequences in the Oracle database schema.
Usually you create a sequence for each table.

Then in the mapping you have to indicate the name of the sequence to Hibernate.

5.1.4.4. Identity columns and sequences

Before inserting a new record Hibernate will query the next value in the sequence
SELECT person_id_sequence.nextval FROM DUAL
and then use it as the new key.

If you do not specify a version or timestamp for concurrency control (which you really should) you need to indicate the "unsaved-value" attribute in the "id" element so that hibernate can tell whether the object is a new one. The value that you specify must be the value that you set in the class initialization or class constructor.
5.1.4. id

5.1.7. version

5.1.8. timestamp
ben oliver
Ranch Hand

Joined: Mar 28, 2006
Posts: 374
Originally posted by Peer Reynders:
First you have to set up the appropriate sequences in the Oracle database schema.
Usually you create a sequence for each table.

Then in the mapping you have to indicate the name of the sequence to Hibernate.

5.1.4.4. Identity columns and sequences

Before inserting a new record Hibernate will query the next value in the sequence
SELECT person_id_sequence.nextval FROM DUAL
and then use it as the new key.

If you do not specify a version or timestamp for concurrency control (which you really should) you need to indicate the "unsaved-value" attribute in the "id" element so that hibernate can tell whether the object is a new one. The value that you specify must be the value that you set in the class initialization or class constructor.
5.1.4. id

5.1.7. version

5.1.8. timestamp


1. Assuming I use oracle, can I use class = "native" instead of "sequence" ?

2. By the way, I assume your answer to my last question was -- yes, Hibernate will just generate the unique id for me, and it's behind the scene (e.g. developers don't need to explicitly programatically deal with the unique id), is that right ?
pascal betz
Ranch Hand

Joined: Jun 19, 2001
Posts: 547
ID property (from chapter 6.1.4 of the reference manual):
Mapped classes must declare the primary key column of the database table. Most classes will also have a JavaBeans-style property holding the unique identifier of an instance. The <id> element defines the mapping from that property to the primary key column.


you can hibernate let take care of the PKs and FKs. as long as your "cascade" attribute is correct it will save everything. otherwise it will throw an "Transient Object Exception" (dont know the exact name):
if there is a relationship mapped but the related entity is not yet saved (that is: the ID property has the "unsaved-value") and there is no cascade specified for persist/save operations then hibernate will tell you trough this exception that something is wrong.


i know you did not like my "did you try" comment... but i think it would be best if you do some small "experiments" to get a understanding of the hibernate concepts/wording (entity/detached/attached/persistet/transient/cascade/key generation/relationships/...). it will make it easier for you to understand the comments/answers given.
and yes:
If I just try this concrete scenario and find it doesn't work, it does NOT mean it can't work --- Maybe it is because I am a newbie and I don't know the right way to do it.


but then you can just post what you did so far, what you happened and what you expected/wanted to happen and we can help you.

anyway: hibernate is pretty flexible in it's mapping options/possibilites.

pascal
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2921
    
    5
Originally posted by ben oliver:
1. Assuming I use oracle, can I use class = "native" instead of "sequence" ?

No, you cannot. As stated under 5.1.4. id Oracle does not support identity columns � if you want database generated keys you will have to create sequences in the database first. Keep the Oracle documentation at arms length. Thomas Kyte's Expert Oracle Database Architecture: 9i and 10g Programming Techniques and Solutions and R.M. Menon's Expert Oracle JDBC Programming are also good resources.

Originally posted by ben oliver:
2. By the way, I assume your answer to my last question was -- yes, Hibernate will just generate the unique id for me, and it's behind the scene (e.g. developers don't need to explicitly programatically deal with the unique id), is that right ?


I already outlined in my previous post what Hibernate will do:

Before inserting a new record hibernate will query the next value in the sequence
SELECT person_id_sequence.nextval FROM DUAL
and then use it as the new key.

So in fact it does not generate the ID � it obtains the ID from Oracle. And yes, that will happen without Java code from the developer but it requires that the developer set up the correct configuration in the hibernate mapping � from the set up and mapping of the sequences, proper setting of the cascade attribute on the relationships, unsaved-value attribute settings, etc. � from that point of view, its far from "automatic".
ben oliver
Ranch Hand

Joined: Mar 28, 2006
Posts: 374
Thanks fellows. I agree it is cool to use oracle sequence as PK and FK and let hibernate get them and insert into table. But, as Paul Sturrock just mentioned in another thread --- If tables just use such PK, how can the application that does NOT use hibernate use your database tables ?

I sort of agree with Paul Sturrock on that -- in many cases, we have some raw input data file and SQL loader can load them, the file format usually resembles the columns format without having such oracle sequence id. If we introduce sequence PK, how can we load such files ?? plus, for plain jdbc applications, how do they insert values into the table (they don't have such hibernate mapping xml file) as they don't know the value of sequence id ?? When they (non hibernate applications) retrieve your table data, they can't take advantage of the sequence id, they still have to query on other business related fields...

Please help on this question if you can.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: cascading classes and tables (how to update ?)
 
Similar Threads
Foreign key problem
Replacing *.hbm.xml files with @Annotations.
Exception in Deleting Parent and Child entity
Composite Foreign Key that maps to Unique Constraint
Mapping same POJO to two tables in Hibernate XML mapping files