Hibernate Sessions between HTTP requests - java

I'm developing a web application in which the model consists a Group which contains a List of many Users. A HTTP request comes to show the Group. The Users are loaded with FetchType.LAZY because I don't want them all right away. The Group is saved into the HTTP session and the Hibernate Session is closed. The application then responds by showing the Group name and description. A new HTTP request might then come in to show some users from the group. The Group is pulled from the HTTP Session and the application tries to access the list. Won't Hibernate throw an Exception since the proxies for each User were tied to the Hibernate Session that was previously closed? How do I do lazy loading across HTTP requests within HTTP sessions?

You should not put users nor groups (as objects) in the session. The best scenario is to put group id in the session and load the group and users if/when necessary.
Worried about the performance? Let the Hibernate 2nd level cache solve this problem. The cache should even support retrieving all users by group if you configure object mappings correctly, something like:
<class name="Group" table="...">
<cache .../>
<bag name=users" ...>
<cache ....>
...
</bag>
</class>

I don't think you need to or should store it in session. When you need the association you query it.
Update
Refrain from Eager loading, unless the collection size is small or managable. For example you have a Groups with small number of users in each group.
If you have reverse mapping, you could use group id to query the user list in subsequent calls.

Have you considered Open Session In View?
Open Session In View

Related

Is it possible to set session id (or JSESSIOINID) value manually in Java?

As the title says. In PHP for example I can set the session id manually to handle the session with some logic based on it. I have generated hash code from some workflow and would like to set it as the session id. I know some implied this could be bad practice if not careful but as team member I was directed to look and try to do this task.
So could session ID set manually ?
Note that I mean the actual session ID not just the cookie named JSESSIOINID that being set on first request. I need the session as it is with only session id set manually.
Update: I'm using JBoss but I'd appreciate any generic answer or at the very least for JBoss EAP.
For Tomcat, you may be able to create a custom session manager (see this). You would then have access to the Tomcat Session object and could call setId(java.lang.String id).
No standardized way to it. Only custom way through the container's own API

Allowing access for specific users in Spring Security

I'm using Spring Security to Secure my Web App.
I have a page where I show foo objects for administrators.
<intercept-url pattern="/show_foo/**" access="hasRole('ROLE_ADMIN')" />
But now I have a requirement that a foo cannot be seen by all the Administrators, for example only administrators with city="New York" can access to the element.
I've did something in my controller to solve this :
#RequestMapping(method=RequestMethod.GET,value="/show_foo"
public ModelAndView showfunction(Principal user)
{
User user2 = userService.getUserByName(user.getName());
if(/* some checks on user2 */)
/* show page */
else
/* show error page*/
}
So my question is : can I avoid the database call, because I need this almost in all of my pages and I find it ugly to check each time at the top of any controller the same thing over and over. Is there a Spring Security feature for this kind of use cases?.
With Expression based rules you can accesss principal even on rule. See: http://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html
For example if you can include needed information on principal object.
<intercept-url pattern="/show_foo/**" access="hasRole('ROLE_ADMIN') and principal.name=='xyzzy' " />
you have to put in some logic.
1.) Either load the user and country mapping and store somewhere in Static HashMap, remember to update the map if any changes done in mapping, can store same at session level.
2.) Load entries in 2nd level cache, or make queries cacheable, enable query caching as well.
You need to integrate Spring Security with Domain-ACLs. See a full explanation here.
Yo can consider mapping the relationship between Administrators and Cities using
ACL_OBJECT_IDENTITY instances.

Java Hibernate OpenSession in View Avoid fetch on Controller

we have a APP in Hibernate lately we start using Open Session in View in our DAO we fetch the data we really need.. we dont close the session but later in our controller in any operation on the Entity Hibernate is fetching the Data from the DB i know this behavior is the main reason to use open session but i dont need the fetch is some cases.. i was wondering if i can tell hibernate not fetch the data in some cases....
student.getSchool().getTeachers()
in this case i have load all the data i need from this 3 entitys but hibernate starts to load the school and the teachers again..
thanks a lot
Three main options:
If you use EH-Cache, you won't have to wait while Hibernate queries the database for Student & School again.
Or you could keep the form & Hibernate Session in the HTTP Session, which also achieves caching.
For AJAX or similar requests fetching just the Teachers, you could change the Criteria to Projection or use a Hibernate Query, to "project" or retrieve just the target entity.. at the database level, doing a joined or sub-expression query. Student would be loaded but only as a proxy, in this case.

Why did app engine perform writer operation when I "read" HttpSession Attribute

the write operation on the httpsession is consuming my resources
I have a on UserSession attribute in the session which only store a userID and hash
write operation should only perform while login
but each time I use UserSession in my controller datastore_v3.Put was performed
what is happening???
I am using spring mvc in my project
I suspect that the session state is being saved because Spring MVC has no way of knowing if the state of the session-scoped objects has been changed during the request.
It's probably updating the timestamp of your session to keep it fresh on every access.
If you're really curious, you can get to the low-level session data using (I believe) the _AH_SESSION table (do a query on table Query.KIND_METADATA_KIND in empty ns for the full list of tables, including "hidden" tables).

Mixing JTA and JDBC transactions

I have a Java SE(!) scenario with JMS and JPA where I might need distributed transactions as well as "regular" JDBC transactions. I have to listen to a queue which sends service requests, persist log on receiving, process the request and update the log after the request has been processed. The message shall only be acknowledged if the request has been processed successfully.
The first idea was to only use JTA (provided by Bitronix). But there I face two problems:
no log will be persisted if the request can't be processed
the request won't be processed if the log can't be updated (unlikely but yet possible)
So the other idea is to create and update the log with regular JDBC transactions. Only the entitymanager(s) for the request transaction(s) would join the user transactions and the entity managers for creating and updating the log would commit directly.
Is it possible to "mix" JTA and JPA on a single persistence unit? Or do we already have patterns for those kinds of JMS and JDBC transactions?
I actually solved my problem with a slightly different approach. Instead of "mixing" JTA and JDBC transactions I used suspend and resume to work with different user transaction.
The task is still the same: I start a (JTA) user transaction that contains some JMS and JDBC transactions (receiving a message, performing some database operations). And in the middle of that workflow, I want to write a message log but that logging shall not be rolled back when the "outer" transaction fails.
So the solution is, in pseudo code:
transactionManager.begin()
doSomeJdbcStuff();
Transaction main = transactionManager.suspend();
// do the logging
transactionManager.begin() // <- now a new transaction is created and active!
doSomeLogging();
transactionManager.commit()
// continue
transactionManager.resume(main);
doSomeMoreJdbcStuff();
transactionManager.commit();

Categories

Resources