File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Object Relational Mapping and the fly likes Help needed on the following example? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Help needed on the following example?" Watch "Help needed on the following example?" New topic
Author

Help needed on the following example?

Joe Harry
Ranch Hand

Joined: Sep 26, 2006
Posts: 9350
    
    2

Guys,

The following example is from the Hibernate in Action book,

1 Updating a Message:

Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
// 1 is the generated id of the first message
Message message =
(Message) session.load( Message.class, new Long(1) );
message.setText("Greetings Earthling");
Message nextMessage = new Message("Take me to your leader (please)");
message.setNextMessage( nextMessage );
tx.commit();
session.close();


2 This code calls three SQL statements inside the same transaction:

select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
from MESSAGES m
where m.MESSAGE_ID = 1
insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
values (2, 'Take me to your leader (please)', null)
update MESSAGES
set MESSAGE_TEXT = 'Greetings Earthling', NEXT_MESSAGE_ID = 2
where MESSAGE_ID = 1


The Message POJO class is as below,

package hello;
public class Message {
private Long id;
private String text;
private Message nextMessage;
private Message() {}
public Message(String text) {
this.text = text;
}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Message getNextMessage() {
return nextMessage;
}
public void setNextMessage(Message nextMessage) {
this.nextMessage = nextMessage;
}
}


The xml mapping file is as below,

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="hello.Message"
table="MESSAGES">
<id
name="id"
column="MESSAGE_ID">
<generator class="increment"/>
</id>
<property
name="text"
column="MESSAGE_TEXT"/>
<many-to-one
name="nextMessage"
cascade="all"
column="NEXT_MESSAGE_ID"/>
</class>
</hibernate-mapping>


My question here is, how 2 (in bold) happens when we have 1 (in bold)??


SCJP 1.4, SCWCD 1.4 - Hints for you, Certified Scrum Master
Did a rm -R / to find out that I lost my entire Linux installation!
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

OK, when you call load first, that does the Select statement, and it also puts the object into the Session aka Persistence Context. When you change the text, Hibernate now knows that that object in its Session has changed and it will need an update statement. Now, however, because you create a new Message and connect it to the object that is in the Persistence State, It will need to insert the new message into the database first, because if it isn't there it can't update the object that is in the Session. The update to the database would fail because of the FK to the new message.

Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Joe Harry
Ranch Hand

Joined: Sep 26, 2006
Posts: 9350
    
    2

Where is the FK coming in place?? All 3 columns belong to the same table. I'm still unclear as to why the insert happens first and then the update?
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

Yes, but the third column is a self referring Foreign Key.

So I have a message

id
message
another_id_pointing_to_a_different_record_in_the_same_table




The 2 in the next_message_id is pointing to the next record which has id=2.
So in order for next_message_id to have a value of 2, the record with id of 2 must be inserted first. because if you have next_message_id being 2 and no such record with id being 2, then you have bad data, there is no referential integrity there.

Mark
Joe Harry
Ranch Hand

Joined: Sep 26, 2006
Posts: 9350
    
    2

Ok Mark, I got to understand this. So in such a scenario, even when you update a record and then insert a new record, the reverse happens automatically. Am I right when I refer to the case above where I issue an update first and then insert, but the actually insert happens first and then an update?
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

Basically this is the scenarion.

If you tried to update the first record without the second record ever being inserted into the database, how does the first record know the ID of the second record.

Showing the steps in the database

You start off with just one record



Now you change the message to "hello" and you added a new Message to its second message the new second message is "world"

If you tried to first update the first record before inserting the new second message what would be the value of the next_message_id?



So Hibernate is smart enough to know, hey I can't set the next_message_id because right now the second message has an id of basically "null" it does not exist in the database to even have an id. So instead Hibernate inserts the second message first

So it would do this, first insert the second record


And then do the update on the first record



Mark
Joe Harry
Ranch Hand

Joined: Sep 26, 2006
Posts: 9350
    
    2

Wonderful Mark! Thanks for your explanation. So this is taken care by Hibernate automatically. Am I right?

Thanks for your help!
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

Originally posted by Jothi Shankar Kumar Sankararaj:
Wonderful Mark! Thanks for your explanation. So this is taken care by Hibernate automatically. Am I right?

Thanks for your help!


Yep.

Mark
 
Don't get me started about those stupid light bulbs.
 
subject: Help needed on the following example?