-->
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.  [ 4 posts ] 
Author Message
 Post subject: Intermittently not saving foreign keys in one-to-many
PostPosted: Fri Sep 03, 2004 4:52 pm 
Newbie

Joined: Fri May 07, 2004 2:18 am
Posts: 19
Hibernate version 2.1.6:

Mapping documents:

Session session = HibernateUtil.currentSession();
Transaction tx= session.beginTransaction();
doEntity(entity);
session.saveOrUpdate(entity);
doEntity(entity)
session.update(entity);
tx.commit();
HibernateUtil.closeSession();



Mysql 4.20:

Hello I have a very weird problem.

I have a class named entity.

/**
* @author Marcus
* @hibernate.class table="entity"
*/
public abstract class Entity implements Externalizable{
public static final long serialVersionUID = 1;
private Long id;
private List notes = new ArrayList();

/**
* @hibernate.id generator-class="native"
*/
public Long getId() {
return id;
}


public void setId(Long id) {
this.id = id;
}

public void setId(long id) {
this.id = new Long(id);
}

/**
* @hibernate.bag inverse="false" lazy="true" cascade="all-delete-orphan"
*
* @hibernate.collection-key column="entity"
* @hibernate.collection-one-to-many class="org.marcus.Note"
* @return
*/

public java.util.List getNotes() {
if(notes == null)notes = new ArrayList();
return notes;
}


public void setNotes(java.util.List notes) {
this.notes = notes;
}

public void addNote(Note note){
if(notes == null)notes = new ArrayList();
note.setEntity(this);
notes.add(note);
}
}

and I have a class called note

/**
*@hibernate.joined-subclass table="note"
*@hibernate.joined-subclass-key column="id"
*/
public class Note extends Entity implements Externalizable, Comparable {
public static final long serialVersionUID = 1;
private Entity entity;
private String type;
private String subject = "";
private String content = "";
private long foreignid = 0;
private int foreigntype = 0;
/**
* @hibernate.property
*/
public long getForeignid() {
return foreignid;
}


public void setForeignid(long foreign) {
this.foreignid = foreign;
}

/**
* @hibernate.property
*/
public int getForeigntype() {
return foreigntype;
}


public void setForeigntype(int foreigntype) {
this.foreigntype = foreigntype;
}

/**
* @hibernate.many-to-one not-null="true"
*
*/
public org.marcus.Entity getEntity() {
return entity;
}


public void setEntity(org.marcus.Entity entity) {
this.entity = entity;
}

}

and I have a function called doEntity(Entity entity)

doEntity(Entity entity){
int id = 0;
if(entity.getId() != null){
id = entity.getId().intValue();
}
int type = 1;
Iterator i = entity.getNotes.iterator();
while(i.hasNext(){
Note note = (Note)i.next();
note.setEntity(entity);
note.setForeignid(id);
note.setForeigntype(type);
}
}

I created doEntity when this problem started occurring because I wasnt sure where it was happening and decided to play it safe.
Everything works fine except that every once in a while the entity property of note is not populated and instead the database column for entity is 0 and not the entitys id

I get no exceptions and in my note table the foreign key column always has the correct entity id. You will notice that i actually call deEntity twice. This is because the entity may be new and therefore their is no identity id for me to put into foreignid.

The entity objects and notes are actually detached instances before they reach session.saveOrUpdate. They are sent using rmi and implement externalizeable. The code above is the only path any object has into the database.

Please note that everything works fine except for this intermittent problem
The problem crops up as
UnresolvableObjectException: No row with the given identifier exists
Which is obviously the case because no Entity object has an id of 0.
When I do a select * from note where entity = '0';
The foreignid column has the correct value;

I would love to give you more info but as I said it is intermittent and I have yet to recreate it. It seems to only happen on a live production machine. i.e many simultaneous users.
The server is running redhat linux 7.3 with blackdown java 1.4.2

Any help would be appreciated

Marcus


Top
 Profile  
 
 Post subject: I found the answer
PostPosted: Sat Sep 04, 2004 10:23 pm 
Newbie

Joined: Fri May 07, 2004 2:18 am
Posts: 19
Hello

This is in response to my own post. After much testing I found that the problem stems from from hibernates behaviour when you pass it a detached object that contains a collection in a one-to-many relationship and your detached object contains fewer objects in its collection than exist in the databases. Hibernate will change the value of the foreign key for any missing objects to 0. I have no idea what justifies this behaviour.

As in the example in my post. Lets say I have one entity object and it has 4 notes and they are all saved to the database. This entity object is then detached and sent via rmi to some other process where one of the notes is removed from the collection and then passed back to database tier. When the following sequence occurs
Session session = HibernateUtil.currentSession();
Transaction tx= session.beginTransaction();
session.saveOrUpdate(entity); //with one fewer note objects
tx.commit();
HibernateUtil.closeSession();

Right after the commit the database will contain the original entity object and the 4 note objects except that the one note object that was removed from the collection that was detached now has its entity field filled with the value 0
What makes putting what is essentially a random number into the field better behaviour than just leaving it alone. At least that way you would quickly become aware of the flaw and not just have the database throw a foreign key violation or just fill up with unreferenced entries

Marcus


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 04, 2004 10:48 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Hibernate most certainly does not set any foreign keys to zero. Most likely you have a default value on your table, or a trigger or something like that.

Also, you have not read the documentation, and have not mapped your parent/child relationship correctly.

When you see strange behavior, please start by assuming that it is your fault, not ours, that we we will all get along much better. :-) Thanks.


Top
 Profile  
 
 Post subject: Whoops. My reply to my reply
PostPosted: Sun Sep 05, 2004 12:26 am 
Newbie

Joined: Fri May 07, 2004 2:18 am
Posts: 19
Sorry folks. I had the association wrong. The entity --> note collection should have been mapped as inverse=true

Truly a maddening maddening pain in the but to diagnose.

A new question has come to mind. Anybody know how to resave a deleted object in a different session with session.save without having hibernate checking the unsaved value and calling update instead of insert

Marcus


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