-->
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.  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Compare same objects from different sessions
PostPosted: Thu Feb 14, 2008 10:02 am 
Beginner
Beginner

Joined: Tue May 29, 2007 3:14 am
Posts: 28
What do I have to do, that when I compare two objects from different session, the result returns true?
At the moment I get "false" when I compare them.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 14, 2008 6:34 pm 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
This is because the default equality operation is based on instance equality. If you want to be able to compare entities from different sessions you will need to override the Equals and GetHashCode methods on your classes. See the documentation for details.

Cheers,

Symon.

_________________
Symon Rottem
http://blog.symbiotic-development.com


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 15, 2008 4:55 am 
Beginner
Beginner

Joined: Tue May 29, 2007 3:14 am
Posts: 28
This works fine.

But now I have several other problems. Trying to perform an update or delete an object I get errors like "a different object with the same identifier value was already associated with the session".

Maybe I should explain my whole changes in program. At the beginning I worked with only one Session for the whole program. Now I modified the program and use for each transaction a separate session. Before these changes updating and deleting these objects worked without errors. Does anybody has an idea what the reason for such errors could be concerning the multiple sessions?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 15, 2008 4:59 am 
Beginner
Beginner

Joined: Tue May 29, 2007 3:14 am
Posts: 28
And another question, what can I do to improve the performance of the program? Its really slowly since these changes.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 15, 2008 8:48 am 
Beginner
Beginner

Joined: Tue May 29, 2007 3:14 am
Posts: 28
-deleted-


Last edited by ___Amelie___ on Fri Feb 15, 2008 8:52 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 15, 2008 8:51 am 
Beginner
Beginner

Joined: Tue May 29, 2007 3:14 am
Posts: 28
Maybe an example will help. What I'm doing is something like this:

Form1:
Session1 = Factory.OpenSession
Dim list as IList = Session1.CreateQuery...
list(0). 'Change the object
Session1.Save(list(0))
Session1.Connection.Close()
'I Only close the connection, because when I close the session I
'cann't use the list
Session1.Connection.Open()
Dim list as IList = Session1.CreateQuery... 'another one
list(0). 'Change the object
Session1.Save(list(0))
Session1.Connection.Close()

Form2:
Session2 = Factory.OpenSession
Dim list as IList = Session2 .CreateQuery...
list(0). 'Change the object
Session2 .Save(list(0))
Session2.Connection.Close()
'I Only close the connection, because when I close the session I
'cann't use the list
Session2 .Connection.Open()
Dim list as IList = Session2 .CreateQuery... 'another one
list(0). 'Change the object
Session2 .Save(list(0))
Session2 .Connection.Close()

For each form I create a Session and also for each shared method.

The error I get in this case: "Illegal attempt to associate a collection with two open sessions"

It think, this error and the one I wrote 2 replys before have the same reason.

I'm not shure, if closing the connection is correct, but closing a session doesn't work.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 15, 2008 2:01 pm 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
That seems like a convoluted use pattern. What are you trying to accomplish?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 16, 2008 12:46 pm 
Beginner
Beginner

Joined: Tue May 29, 2007 3:14 am
Posts: 28
There is nothing special I want to do. It's a normal application. For each form there is a Session and for each operation I open and close the connection of this Session. Before my changes I used only one Session for the whole program and everything worked. But I have a service which uses some classes of my application. The classes itself have some methods performing database queries and this service does parallel database queries. So I needed more Sessions and thats why I modified the whole program.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 18, 2008 2:53 am 
Beginner
Beginner

Joined: Tue May 29, 2007 3:14 am
Posts: 28
Code:
Dim Session as ISession = Singleton.GetNewSession() //returns an open Session
Dim list as Ilist = Session .CreateCriteria(GetType(ClassA))

list(0).Name = "Test"
Session .Begintransaction()
Session .Save(list(0))
Session.Commit()
Session.Connection.Close() 'To be able to use the Session again, I only close the Connection. Closing the Session doesn't work.
.
.
.
list(0).Name = "TestAgain"
Session .Begintransaction()
Session .Save(list(0))
Session.Commit()
Session.Connection.Close()
.
.
.
public ClassA

        Dim Session as ISession = Singleton.GetNewSession()

        Public Property ID() As Integer
            Get

            End Get
            Set(ByVal value As Integer)

            End Set
        End Property

        Public Property Name() As Integer
            Get

            End Get
            Set(ByVal value As Integer)

            End Set
        End Property

        Public Property list() As IList
            Get
                Session.Connection.Open()
                Dim _list As IList = Session.CreateCriteria _
                (GetType(ClassB)).Add(Expression.Eq("ID", 34)).list
                Session.Connection.Close()
                Return _list
            End Get
            Set(ByVal value As IList)

            End Set
        End Property



I'm working with several Sessions. One Session, to get objects from database, and one inside each object to do operations inside these objects.
I'm not sure if the error ("Illegal attempt to associate....") could be the consequence of this scenario. Maybe anybody knows and has a tip for me how to handle this?!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 18, 2008 3:46 am 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
So to be clear, you're trying to save an entity in one session and then, with the entity still in memory but with the original session closed you're trying to create a new session and re-save the entity, right?

If that's the case then the problem is that you can't save an entity twice to your persistent store.

Consider a persistent entity as having a long lifecycle - you save it to NHibernate where it continues to 'exist' even though you may close the session, your session factory and your application. NHibernate is complaining because you then tried to add another entity to the persistent store with the same Id.

If you want to "update" the state of an entity that has already been persisted you can us the Update method or if you don't know in advance if the entity is persistent or transient you can use the SaveOrUpdate method which will make the entity persistent if it was transient or will update a disconnected persistent entity (eg, one saved in another session). It doesn't matter if the entity was actually loaded from another session - if you create a new object in memory that has the same identity as another entity that was previously saved NHibernate will see that as the same entity since it uses the Identity Map pattern.

Note that if you decide to use SaveOrUpdate you need to make sure you have used the unsaved-value attribute in your mapping so that NHibernate can work out whether or not the entity has been assigned an Id - if there's no Id it's not considered persistent. Oh, and I don't think you can use SaveOrUpdate with assigned identifiers...

Also, if you have multiple sessions open at the same time and try to move an entity between sessions you have to explicitly move it's collections as well, if I'm not mistaken. So if you have an entity and it's associated collections saved to session 1 and you want to transfer the entity to session 2 you need to evict the entity and its collections from session 1 before using Update or SaveOrUpdate on session 2.

Cheers,

Symon.

_________________
Symon Rottem
http://blog.symbiotic-development.com


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 18, 2008 4:23 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Sounds like the Hibernate with Fat Client problem once more. See the link before for a german discussion of the problem. I you don't know german, you can at least check out the links at the end of the article.

The short version:
Use one session per dialog.

In order to 'move' a object from one session/dialog to another get a new copy from the target session using session.get()

Everything else I have seen so far causes more problems then anything else.

Nice side effect: You don't need to implement equals or hashCode, since you always work only within a single session.

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 18, 2008 5:00 am 
Beginner
Beginner

Joined: Tue May 29, 2007 3:14 am
Posts: 28
I use already one Session per Dialog/Form. But I think, the problems are the classes. Because each object has a own session.

Code:
public ClassA

        Dim Session as ISession = Singleton.GetNewSession()

        Public Property ID() As Integer
            Get

            End Get
            Set(ByVal value As Integer)

            End Set
        End Property

        Public Property Name() As Integer
            Get

            End Get
            Set(ByVal value As Integer)

            End Set
        End Property

        Public Property list() As IList
            Get
                Session.Connection.Open()
                Dim _list As IList = Session.CreateCriteria _
                (GetType(ClassB)).Add(Expression.Eq("ID", 34)).list
                Session.Connection.Close()
                Return _list
            End Get
            Set(ByVal value As IList)

            End Set
        End Property
end class


I have a lot of classes. These do some operations internal and need a Session. I have to create a new Session for each object of these classes because I have beside my application a service which uses these classes and performs parallel actions. If during this parallel actions (each has a own session) a object of ClassA was created, I wouldn't know where I should get the current Session from (from which action), so that I wouldn't know which existing and open session I have to use in the objects.

To go on like this (to create a Session in each object) I would have to load all entities in my objects with get()? Did I understand correctly?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 18, 2008 5:46 am 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
I think schauder is suggesting that you retrieve the objects again, yes. Whether that's done using Get, Load or a query of some type shouldn't matter, as long as you loaded the instance from the session for the form.

If you are concerned about performance you can use second level caching so you don't have to touch the database every time.

Cheers,

Symon.

_________________
Symon Rottem
http://blog.symbiotic-development.com


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 18, 2008 2:12 pm 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Yep Symon is right.

You'll have to retrieve the objects again.

An object belongs to a dialog/form and uses the session which belongs to the form. And everything that is used inside a form (or an action triggered from a form) should be attached to the session of that form and only to that session.

If an entity gets handed over dialog to another you'll retrive a new instance using the session of the targte dialog.

Example:
you have a browser which lists Thingies and on double click you want to open a ThingyEditor. The code would look aproximatly like this:
Code:
public void mouseClick(Event e){
Thingy t = e.getSource.getSelectedObject();
ThingyEditor te = new ThingyEditor();
Session s = te.getSession();
t = s.get(t.getId()); // creates a new Instance

te.setThingy(t);
}


Of course this isn't real code, but It should demonstrate the concept

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 19, 2008 3:59 am 
Beginner
Beginner

Joined: Tue May 29, 2007 3:14 am
Posts: 28
Ok, I think I understand the problem now.

So I'd need the Session of the Form also in ClassA to get the list?

Has anybody an idea how to design the program to handle this?

Thanks for the help!!!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next

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.