Using NHibernate with ASP.NET 4.
I have had no issues retrieving objects, but I've just got to a point with nested objects that I can't figure out.
I am using lazy=true and when accessing a lazy-load collection I get the message:
Initializing[type#3]-failed to lazily initialize a collection of role: [type], no session or session was closed
Even if I call SessionFactory.OpenSession() immediately prior to the object being accessed, it makes no difference. I have also tried accessing the collection in a using ISession block to no luck.
Edit to add - I do have current_session_context_class = web set in web.config, and I am using CurrentSessionContext.Bind on BeginRequest.
Can anyone offer some advice?
Not an MVC app
I read this - don't know how accurate it is, and it is Hibernate:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2878
It says something about a bug in many-to-many relationships.
Here is my HBM mapping:
<bag name="Objects" table="ObjectInstance" cascade="all" lazy="true">
<key column="branchId" />
<many-to-many class="InventoryObjectInstance" column="objectInstanceId" />
</bag>
Does that happen after you perform some save/update operations? Where and when are you closing the session? To me, it sounds like you close the session right after save call or in some other method before the web page gets rendered. In other words, make sure you are using Open Session in View pattern and close the session only in the end of current web-request. You can also check out this post.
When object graphs are retrieved they keep a reference to the session that spawned them. They use that session for lazy loading of their properties. If the original session is closed, you will get this error (or one just like it) when trying to access them. Opening a new session will not help.
You can try to find where the original request session is being closed and stop that. Are you in the same request though? Failing that you can try to connect your object to a new session -- I think it is Session.Lock(YourObject). Alternatively you could retrieve the object again from the new session.
For some reason you are getting a new ISession when you call SessionFactory.OpenSession(). Is your first use of the session wrapping access to it in a using block? Why are you calling OpenSession again anyway -- what happened to the reference to the session?
Related
When I first started learning J2EE, I was told that, we need to call request.getSession(true) to create a new session. But when I started testing HttpSessionListener, I found that the servlet container will create a HttpSession as soon as it receives a Http request from the client - before I explicitly try to create any session. Is the servlet container implicitly calling request.getSession() or request.getSessioin(true) to create a new session from me?
The only scenario where I found the getSession(true) to be useful is when I want to explicitly invalidate the existing session and create a new one. Is this the only real world scenario or are there any other examples?
But when I started testing HttpSessionListener, I found that the servlet container will create a HttpSession as soon as it receives a Http request from the client - before I explicitly try to create any session
I don't know how you tested it, but unfortunately it is not true. Try to create very simple servlet and put there:
System.out.println("Session: " + request.getSession(false));
you will see that session is null. Container doesn't create sessions, if it is not requested by your application.
You probably got that impression testing jsp pages, or some framework, which by default create session. But this can also be disabled using <%# page session="false" %>, if your page doesn't need session.
And regarding need of request.getSession(true) - you could say it is not needed as request.getSession() does exactly the same, however request.getSession(false) is needed to check, if there is a valid session associated with request.
Related to that question.
I've understood that I have to create some services for handle my entity and so on. That's because I have to "move" my logic away from controllers and place into "managers" (i.e. services)
Now I have a service that have some logic into it. In that service I, depending on user, return a list of "associated object" - say that those object are sport's team.
Let's say that first element of my list (generated from a repository somehow) is the "default" team and say that I have a page were I can change it FOR all session long.
After log out or sessions stale, I want to return at "default" situation.
So my idea was: "since I've wrote a manager for this entity, I'll write a private attribute in this class where load (from db) this property and store (temporarily, with setter method) my changes."
This doesn't affect my db and I can keep my information for all session long.
But a thought came into my mind: how about session object? (is a service, if I didn't understood wrong)
Is my solution a good solution, or is better to store my information into session object?
From my point of view it's the same except that I can read session's variables directly from twig by using app.session. Am I wrong?
Moreover, if I'm not wrong, how can I access my object properties from twig without each time pass them from controller? (is much like having a global variable that I want to display everywhere into my application pages).
Edit:
More information can be found in this chat transcript.
If you want to store a variable for the duration of a session (for example, login until logout or as long as the user doesn't close his browser window) you have to store it in the session object. If you want to store a variable for the duration of a request, you can store it in the manager service.
However, you can use the manager service to load the session variable and make it available to the controller.
Just like it is a good idea to decouple the controller from the database/Doctrine it is also a good idea to decouple the controller from the session.
Update: As mentioned in the comments when looking at REST it is not a good idea to do the session stuff in the service. However, you should still store the variables in the session and use the controller to set the value in the service.
"serialization exception thrown in System.Web.Profile.DefaultProfile"
I'm using a lot of custom classes but have marked them all with serializable attribute. The website loads properly initially on the default page, but once a redirection happens to a different page, which inherits the custom "BasePage" class, instead of the default Page class, this exception is thrown :
Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.
one of the statements in the intellitrace says something like, "failed to serialize System.Web.Profile.DefaultProfile could not be serialized". Isn't it an inbuilt .NET object, and if so cannot I presume that it should be serializable in all cases???
I just ran into this same problem yesterday. The custom object isn't necessarily the problem, but objects inside of that. If you have things like System.Drawing.Image or Dictionary<> or anything else that isn't inherently serializable, its gonna blow up. So you're gonna have to do some digging. I had to do things like convert a List into a string[] to pass it to the web service (which receives a List but shows in intellisense as receiving a string[]).
So I'd rethink that. We also found out that once we got that working in the test server, we weren't done. As soon as we published the web service, other problems started popping up that were similar. Images were not serializable so we converted them to byte[] before sending them, Dictionaries were also not serializable.
I realize this isn't much of an answer, but hopefully of some help.
It is built into ASP.Net, but that doesn't mean it's serializable. There's lots of framework classes that are not serializable.
But also, the Default profile is made to work with the asp.net profile mechanism. Why are you attempting to store that in session? It already has it's own configurable storage mechanism. I think this may be a case where you're in a place where you're fighting the system.
For my particular case, I worked around the problem by creating a new custom class with a Serializable attribute, with a property that would return the HttpContext.Current.Profile object. And then whenever I needed to add the profile into session, I'm adding it through the property of this newly created class. Thanks to #swannee and #Sinaesthetic for their ideas.
In my ASP.NET application I created a custom thread. The thread is updating the session. When I am using InProc session state it works well, but when using SQLServer session state the session is not being updated. Any ideas?
I can't find documentation to back it up, but I think that the SqlServer session state will serialize the Session to the database at the end of the request processing. So anything that's changed after that time is ignored as a new request will get the session from the database.
What are doing in that process is important ? It seems that you are updating some object that stored inside session.
Now it is working with InProcess and not with Sql means you have problem with object serialization.
IF you are using some class whoes instance stored in Session that make that class serializable.
If this not help you please provide more information.
Thanks.
To see a practical example of what is going on check out this question (with example code) I posted a few days ago.
I don't think there is a way to "let the main thread know it should wait before it serializes to the data store". You just have to wait until the background thread finishes. Which kinda defeats the purpose of using the background thread in the first place.
I am using NHibernate on a new ASP.NET project, and am running into what I believe to be strange behavior. I am attempting to manage my session by using an HttpModule to catch the EndRequest event and close the session. This is working fine, however, after the EndRequest event fires, I am getting an exception in the OnLoad event of one of my custom controls that is attempting to read a Property from my object that is lazy loaded. I get an exception stating 'failed to lazily initialize a collection, no session or session was closed'. Turning lazy load off for these properties does fix the problem, and is an acceptable solution. But this seems to be going against what I always thought to be true.
I would assume that the OnLoad event and all server side processing would be done at the point that EndRequest is fired. This is also the first time that I have used IIS 7 on a project. Is this a reason for the behavior? What is the expected behavior?
I just had a 'palm slaps forehead' moment. Despite the fact that I am in fact deploying to an IIS 7 server, I have been debugging using the VS 2008 Built in Web server (Casini). Casini passes all requests through the ASP.NET pipeline, IIS does not. This was causing a request for an image file or javascript file (or any other static resource) to close my NHibernate session before I was actually thinking it should close.
Thanks for the list of resources, I will certainly look into them.
If your object is lazy-init and no session is open, resolving the properties will fail.
Remember that lazy exceptions will most probably appear when you have some relationship with another entity that hasn't been initialized.
http://forum.springframework.org/showthread.php?t=13474
I would also recommend using something like the HTTP Module in Rhino Commons to manage your NHibernate Sessions.
You should use a shrinkwrapped package for dealing with this.
I like to use Autofac with ASP.NET/MVC integration. You simply ask the RequestContainer for an ISession whenever you need it and, because the ISession is IDisposable, the RequestContainer automatically knows to dispose of the ISession when the current request ends. Everything is taken care of for you.
use HttpModule if you need lazy loading. Inherit your class from it and then you'd have two methods you can override (can't remember their names). First one is called each time any page is requested. Open the session there and put the session in viewstate. The other method is called when page is posted back, close your session there.