-->
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.  [ 7 posts ] 
Author Message
 Post subject: problem with a transient collection
PostPosted: Tue Mar 22, 2005 10:53 am 
Newbie

Joined: Thu Feb 03, 2005 5:49 am
Posts: 19
I have two classes A and B.
the A class has a collection of B instances.
I'm using the following tag in the A class mapping.

<bag name="lst_B"
table="TABLE_B"
inverse="true"
lazy="true"
cascade="all-delete-orphan">
<key column="ID_A" not-null="true"/>
<one-to-many class="B"/>
</bag>

I'm using the following tag in the B class mapping.

<many-to-one name="lnk_A" class="A"
column="ID_A"
not-null="true"/>

I'm executing a program in order to execute the following sequence of task
1 - Insert A in the data base (and the B intances by reachability persistence)
2 - detaching A from the session (closing it)
3 - attaching A to a new session (using Session.update in order to propagate changes from A to data base)
4 - detaching A from the session (closing it)
5 - attaching A to a new session (using Session.load(objectA,LockMode.NONE) in order to not propagate changes from A to data base)
6 - making A transient (using Session.delete)
7 - making A persistent again (using Session.save)

the two last steps (6 and 7) use the session created by step number 5.

THE PROBLEM IS THE LAST STEP (7) perform a SQL insert for A but SQL update for the B instances.

In other words, is seems Hibernate doesn't realize the B instances are not persistent.

What could be the reason?

Thanks in advanced.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 22, 2005 11:31 am 
Regular
Regular

Joined: Mon Oct 06, 2003 7:17 am
Posts: 58
Location: Switzerland
When you delete object a, object b is not deleted. It is only deleted when you call remove on the collection with b objects (when you set cascade style all-delete-orphan).

Reto


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 23, 2005 5:26 am 
Newbie

Joined: Thu Feb 03, 2005 5:49 am
Posts: 19
hello Reto, thanks a lot for your help.

I forgot to say that Hibernate deletes both the A and B instances from the data base so all of them become in transient object. In that way when I use Session.save(A) hibernate should insert both A object and B intances collection in the data base, doesn't it?

I'm debugging the execution of my program and I looking throught the hibernate code and in fact the problem is hibernate thinks the b intances collection is detached (but it's transient)

When the execution of my program arrives the following method of the DefaultSaveOrUpdateEventListener class:

protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {

// use various roles to determine if the instance is
// transient, persistent or detached:

int entityState = getEntityState(
event.getEntity(),
event.getEntityName(),
event.getEntry(),
event.getSession()
);

switch (entityState) {
case DETACHED:
entityIsDetached(event);
return null;
case PERSISTENT:
return entityIsPersistent(event);
default: //TRANSIENT or DELETED
return entityIsTransient(event);
}

}

When the event is the saving of B instances collection the method returns DETACHED and, of course, entityIsDetached is performed and, of course, a SQL UPDATE is performed.

Moreover, from getEntityState method the execution arrives to isUnsaved(Serializable id) method in org.hibernate.engine.Cascades class.

this method is executed with id == Long(24) and value == Long(0) and
returns FALSE. So for hibernate my B objects are not Unsaved (but they are)


public Boolean isUnsaved(Serializable id) {
if ( log.isTraceEnabled() ) log.trace("id unsaved-value: " + value);
return id==null || id.equals(value) ? Boolean.TRUE : Boolean.FALSE;
}

I change my program in order to do not use the same session to delete and save the A object instead of that I'm closing the session in which I perform Session.delete(A) after I'm creating a new session but nothing changes.
I set to true the use_identifer_rollback property in my hibernate configuration file.

but after all, if the B instances have value in the id property, hibernate mark them as DETACHED object. In the other hand the A object is being marked as TRANSIENT object (and it has value in the id property)

Shouldn't Session.delete method set to null the id property?
Should I set to null the id values in all my instances of every persistent collection?

Any idea?

Thanks a lot.

P.D.

I'm using:
hibernate 3.0
Oracle 8.1.7
Sequence id generator algorithm


Top
 Profile  
 
 Post subject: Re:
PostPosted: Wed Mar 23, 2005 8:54 am 
Regular
Regular

Joined: Wed Mar 23, 2005 8:43 am
Posts: 105
Location: Moscow, Russia
I don't think that is answer, but:
Do you really need steps 5 and 6? You can make object transient without attaching it to Session(with update() or lock()), make call Session.delete(detObj) with detached object.

_________________
Best Regards


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 23, 2005 9:06 am 
Newbie

Joined: Thu Feb 03, 2005 5:49 am
Posts: 19
hello lester, you're right.

If I delete the object A int the 6th step, I don't need the 5th step.

Actually I'm starting a huge project in which we are going to use hibernate.
I'm haven't use hibernate before and I started executing a comprehensive test of hibernate in order to learn and prove.

But I likely will in that situation in the future so I would like to find out the reason of the problem.

Anyway, thanks a lot.

Sambuko.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 23, 2005 9:33 am 
Regular
Regular

Joined: Mon Oct 06, 2003 7:17 am
Posts: 58
Location: Switzerland
You are right, with all-delete-orphan you have not to explicit remove the object b from the collection. Object b is also deleted when object a is deleted.
When I check your mappings everything should be fine and you also commit the transaction and close the session before you save again object a. Maybe you can post some code from the test your doing?

Reto


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 23, 2005 10:01 am 
Newbie

Joined: Thu Feb 03, 2005 5:49 am
Posts: 19
Here you are the problematic fragment of my testing program

//VentaDocumental == object A
//VentaDocumental contains several collections of other classes


//Becomes vd from persistent to transient (step #6)
VentaDocumental vd = pruebaPersistente2Transitorio(vd);

//Close the session that was created previously
gs.cierraSesiones();

//Becomes vd from transient to persistent (step #7)
vd = pruebaTransitorio2Persistente(vd);


private static VentaDocumental pruebaTransitorio2Persistente(
VentaDocumental vd)
throws HibernateException, ExcepcionSCI
{
//Retrieves the current sesion and begins a transaction
Transaction t = SesionUtil.sesionSCIActual().beginTransaction();

//Insert object a in the data base
vd.insertar();

t.commit();

return vd;
}

private static VentaDocumental pruebaPersistente2Transitorio(
VentaDocumental vd)
throws ExcepcionSCI
{

//retrieves the current sesion and begins a transaction
//(creates a new one if there's no current sesion)
Transaction t = SesionUtil.sesionSCIActual().beginTransaction();

//delete the object a from the data base
vd.borrar();
t.commit();

return vd;
}

***********VentaDocumental's methods*************

public Serializable insertar()
throws ExcepcionSCI
{

try {

//Retrieves the current session and saves itself
Serializable s = getSesionActual().save(this);
return s;

}catch(Exception e)
{

ExcepcionSCI eSci = ExcepcionSCI.newExcepcionInterna(this,"insertar()",e);
throw eSci;

}

}

public void borrar()
throws ExcepcionSCI
{
try {

//Retrieves the current session and deletes itself
getSesionActual().delete(this);

}catch(Exception e)
{

ExcepcionSCI eSci = ExcepcionSCI.newExcepcionInterna(this,"borrar()",e);
throw eSci;

}

}

NOTES:

The SessionUtil class use a ThreadLocal variable in order to store the session of the current thread.

The insertar and borrar methods are implemented by the parent class of VentaDocumental



Thank you.

Sambuko.


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