Create Hibernate-Session per Request - java

I just started a simple Java testproject which manages some entities using Hibernate and provides a REST interface to manipulate these objects and provide some additional business logic. The REST interface is created using RESTEasy and Jetty.
Everything works fine so far, but I have the feeling that I'm actually writing too much boilerplate code. As I don't have much experience in these Java frameworks I'm just wondering if anyone could give me a hint on how to improve the situation.
Creting Hibernate Sessions per Request
Well, as far as I understood I have to create a Hibernate session per request and at the end I have to close it. So currently all of my service methods look like this:
Session session = HibernateUtil.getInstance().getSessionFactory().openSession();
...
...
...
session.close();
Is there any way to remove these two lines in order to somehow do this automatically?
Currently my service is registered as a RestEASY singleton. Will changing to a RESTeasy ressource and creating the session in the constructor solve the problem? I think it will solve the problem of creating the session. But wherer to close it?
In C++ this can easily done be creating a scoped object which closes the session at the end. But in Java?
Whenever such a REST request is made I have to check for a valid session (the user has to login previously). Is a ServletFilter the right way to do this?
General: Are there any other patterns or frameworks I should consider using? I mean I want to keep it as simple as possible and especially as I dont have that much experience I dont want to end up using Spring or whatever heavyweight framework. Seems that I'm used to the simplicity of Python and Django but for this little project I have to use Java.
THanks so far!

Hibernate's current recommended approach for managing Sessions is detailed on this wiki page. In particular, I think you need to read the last paragraph: This is all very difficult, can't this be done easier?
In the end, you do need to tell the persistence layer that "I'm about to do something" (which usually also gets the Session to do it with) and "I'm done doing it". You can do it with annotations, or JTA transactions, but that information still has to be communicated!

Inject SessionFactory to your Data Access Object and use sessionFactory.getCurrentSession() to access Hibernate Session object.
you can make use of any of the Factory classes available to implement this..
Then your code should look like this..
sessionFactory.getCurrentSession().save(newInstance);

You should try writing a Filter that does this. Spring's OpenSessionInViewFilter is a good place to start if you need an example.

Related

Is stateless authentication adapted to a per-user database connection?

The issue
I'm working on an application, which, as many applications, starts with a login page before showing any kind of data.
The problem is that my client specifically requested that the credentials entered should be used to access the database.
This means that, instead of running the username / password against a "user" table, they will be used to acquire the user's database personal access.
It was decided by my superiors that this application would be build on top of a SpringBoot skeleton, which happens to be using a Stateless JWT Authentication mechanism.
I'm no expert when it comes to comparing the benefits of Stateless vs Stateful, but if I understood the concept correctly, this means that my application will need to re-establish the database connection with every single request, right?
I'm asking this because we are experiencing very slow response times.
The code seems to hang a little while on database setup related code, such as
dataSrc.getConnection();
or
entityManagerFactoryBean.afterPropertiesSet();
A possible solution?
I've heard of Hibernate's StatelessSession, but I was unsuccessful in setting it up.
I'm not even sure it would help at all, but from what I read, it uses a lower level Hibernate API, which might help mitigate the problem, without much of an impact on the way things are already coded since the SQL operations are exclusively stored procedure calls, which are manually mapped to Java objects.
What I need help with
Basically, I just want answers to 3 questions :
Question 1 :
Should I simply revert to Stateful authentication, because Stateless models are unadapted to my use case scenario?
Question 2 & 3 :
Can StatelessSession system even be implemented in my scenario, and would it make a significant difference on the database connection time?
But, of course, if you know of any other lead that my help me solve my problem without having to revert the whole thing to Stateful, I'm taking it!
Finally got time to answer this (in case someone passes by in the future).
Basically, I had two choices : remove Hibernate altogether or "go back" to Stateful sessions.
I went with the first option, wich I could do only because we had no annotation based mapping between our java objects and our database.
Going Stateful might have been a better approach, but i didn't really know how to do that. I found an impressive amount of articles underlining how to go Stateless, but not how to go back Stateful and... Well... Doing it backward wouldn't be enough, since I would be missing a lot of configuration, so I'd have to research it, and it was a hassle I had no time to deal with.
Using a custom implementation of org.springframework.web.filter.GenericFilterBean, I wrap every incoming request in a custom requestWrapper containing the database connection.
I open / create said connection using the java (low) API : java.sql.DriverManager.getConnection
I can then retreive this connection from my wrapper, wich is vehiculated through the application by Spring by using this code :
ServletRequestAttributes att = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
ContentCachingRequestWrapper springWrapper = (ContentCachingRequestWrapper) att.getRequest();
CustomWrapper myWrapper = (CustomWrapper) springWrapper.getRequest();
myWrapper.getConnection();
Just don't forget to properly close everything to avoid memory leak and you're set.
One would also need to register the driver properly, just by calling the constructor of said Driver in the application main class.

Correct way of using CRUD in JSF

I need advice on a few design principles regarding CRUD operations in my JSF project.
A very simple example:
I have a basic screen with a form that get submitted. In my bean I declare a database connection in my method and a string object which I populate with my script. I modify the string to get the data that have been submitted in the form. This is the way I was taught do it, but I'm suspecting it's not based on solid principles.
So I decided to start using prepared statements. Seems a bit better, but still not perfect in my mind.
My question is: instead of writing a new script for each CRUD method, is it better to perhaps create stored procedures instead, in my mind it looks like much neater code and perhaps has better readability.
Or is there an entirely different way of doing things? The only concerns I have is a very fragile OLTP database.
Your JSF,s should always redirect to a servlet which calls a service method, where you write all your business logic and call your Data Access Object to execute required sql query. U should never use your bean for database connection... You should use DataSource for your data base Connection. And yes a simple preparedStatement is enough to do. You should convert all your strings in your servlet only and then pass it to the next layer with the help of your bean which has your setters and getters for all your form fields.. And your DAo contains all the CRUD operations.
I don't like the idea of using stored procedures because they're hard to port and usually also hard to debug.
I've been working for years with something like this
JSF -> xhtml + #ViewScoped managed bean to accomodate the values
Stateless EJB for transactional methods called from managed beans
Entity DAOs, called from EJBs, reusing basic CRUD methods with generics. I think JPA here is great, specially when they use metamodel type-safe criteria (http://docs.oracle.com/javaee/6/tutorial/doc/gjivm.html)
Nowadays, it´s been easier to work with lightweight JavaEE stacks such as apache TomEE than using prepared statements.

Using and controlling Spring transactions within Struts 2 actions

I have been working for a while on a project with the following components:
Struts2.1.8.1,
Spring 3.0.3
JPA 2.0,
Hibernate 3
I am using Spring's EntityManager magic... But I'm having problems dealing with transactions inside my actions. For instance, I am setting values on my persisted object in several methods within my class, and I want to be able to rollback if the validate method finds a validation error, or commit these changes otherwise. I have already spent quite a long time reading half of the internet for a comprehensive explanation. Unfortunately, no complete examples exist (at least similar to my stack).
I have stumbled with this thread on a mailing list: #Transactional Spring Annotation in a Struts2 Action does not work. The message I'm linking at seems to have a pretty simple and straightforward solution, using a TransactionInterceptor will do the trick it seems... The problem is that I'm not finding useful information regarding this interceptor.
Anyone here has experience with this technology and can spare a tip and a link or two on how to use Spring transactions inside Struts2 actions?
Thanks!
- Edit 1 -
I have set up a test project if you are interested, just download the file and try it out (or inspect it). Thanks!
Generally, controllers/actions/backing beans/etc don't handle transactions. Actions are the web-part of your back-end code - they should only be concerned with gathering request data, and sending response data. The logic itself (including database access) should be done in another layer. E.g. a service layer. So you create another bean, inject it in the action, and make it do the work - userService.register(user). Then configuring transactions on a service layer should be trivial since it is both in the spring documentation and in countless examples:
<tx:annotation-driven /> and #Transactional (btw, make sure you have the <tx:..> now, it might be causing the issue. Even if it works, this does not invalidate my suggestion about the service layer)
I don't like answering my own question, but since I solved this ages ago... I thought I should share the knowledge (or lack of... in this case).
The book I was using to learn about Struts 2 and Spring-JPA-Hibernate, adds the #Transactional annotation right before the declaration of the service class. This is terribly wrong, for all methods (including those that only retrieve stuff from the database) are inside a committable transaction. Long story short everything got committed event if exceptions occurred.
The solution, as Bozho so wisely pointed out, was to look at examples. That is, set your transtactional methods carefully, in my case I set up transactions for the methods that had to write back to the database and everything started to work just fine.
Thanks to Steven and Quaternion too for taking the time to answer my question.
Based on your question, here's what I understand about your problem.
You want to wrap your action invocation in a transaction. If the validate method records validation errors, you want to roll the transaction back. Presumably, you also want to rollback in case of an error.
Solution
Create an interceptor that will:
Start a transaction
Invoke the action inside of a try/catch block
Rollback the transaction if there is an exception or if there are any validation errors on the action (this can be detected using action.hasErrors)
Commit the transaction
You will probably want this interceptor defined pretty early in the stack. I don't know of any pre-built interceptors for this (although there may be some), but it should be fairly easy to assemble.
Update
I don't use Spring, so I can't say how the JPA transaction support works there, but you can handle transactions for your EntityManager like:
try {
entityManager.getTransaction().begin();
// do your thing
entityManager.getTransaction().commit();
} catch (Exception e) {
entityManager.getTransaction().rollback();
throw new PersistenceException(e);
}
This is just a crude example, but it should illustrate the point.

how does spring allow for lazy-loading?

If you have a call in a Dao method like (pseudo code):
return ..getHibernateTemplate( get by id );
Now say that entity has a lazy-loaded collection. Once you return from your Dao using the hibernateTemplate helper method, how come the session stays in scope and allows you to lazy-load a collection?
Is the session initialized and committed at a global level on a per request basis?
Update
Please explain where exactly the call to 'getcurrentsession' is made, and when is it actually closed/committed?
From what I understand, the spring framework has to handle the session lifecycle, where does it do this? at what point the in the requests lifecycle?
It is handling the Unit of work also, where/how?
Once you return from your Dao using the hibernateTemplate helper method, how come the session stays in scope and allows you to lazy-load a collection?
Because the Session hasn't been closed yet and your entity is thus still Persistent (as opposed to the Detached object state). As long as your entity has not been detached, you can lazy load collections and proxies. See chapter 10.1. Hibernate object states for more details on these states (it's very important to understand them and the terminology used).
Is the session initialized and committed at a global level on a per request basis?
With web applications, it's typically per request. As mentioned in the javadoc of HibernateTemplate:
Lazy loading will also just work with an open Hibernate Session, either within a transaction or within OpenSessionInViewFilter/Interceptor.
And if you look at the javadoc of OpenSessionInViewFilter or OpenSessionInViewInterceptor, you'll read that they are slightly different but both binds a Hibernate Session to the thread for the entire processing of the request and provide an implementation of the "Open Session in View" pattern.
Please explain where exactly the call to 'getcurrentsession' is made, and when is it actually closed/committed?
You could look at the sources and use a debugger for this you know :) Look at HibernateTemplate, more precisely the doExecute() method, this is where the session is obtained. For the close/commit, look at the previously mentioned OpenSessionInViewFilter/Interceptor, both have methods for this purpose.
From what I understand, the spring framework has to handle the session lifecycle, where does it do this? at what point the in the requests lifecycle?
I think I covered that part: the session is created at the start of a request and closed at the end.
It is handling the Unit of work also, where/how?
I'm not sure to get this one. To me, Hibernate's Session is an implementation of the unit of work pattern. So this question is actually the same as the previous one.
PS: I provided some links that show that everything is actually clearly documented. Spring and Hibernate have extremely nice documentation and javadoc. Take advantage of that, look at them by yourself, look at the code by yourself, use your debugger, you'll learn a lot more.
Hibernate returns a custom implementation of the collection which does the loading only whenever any of the collection methods is been invoked. This collection has been constructed with the session as argument.
Do a sysout of getSomeCollection().getClass() to see which Hibernate custom class it is and check the appropriate javadocs/sourcecode to see how exactly they did it.
If you ever questioned the sense/use/value of interfaces and declaring against interfaces, now, this is a good example. You didn't see anything from it, did you? ;)
Is the session initialized and committed at a global level on a per request basis?
It's typically initialized on a per-request basis using ... (wait for it)
Please explain where exactly the call to 'getcurrentsession' is made, and when is it actually closed/committed?
It: org.springframework.orm.hibernate3.HibernateTemplate
... is the heart of Spring's integration with Hibernate. HibernateTemplate will initialize the session as necessary (or pull an already existing one from a ThreadLocal store) and provide it to any callbacks you give to the HibernateTemplate#execute* methods.
From what I understand, the spring framework has to handle the session lifecycle, where does it do this? at what point the in the requests lifecycle?
Also done by HibernateTemplate, and ...
It is handling the Unit of work also, where/how?
Done by HibernateTransactionManager, if you have one configured in your applicationContext.
If this was a web application I would use the OpenSessionInViewFilter

How do you create a DAO class for Seam / JPA (hibernate)?

I'm learning Seam and JPA/Hibernate and while I could find some examples on how to build a DAO class with Hibernate I'm a bit confused on how to do the same thing with Seam (or even if that is at all necessary).
I do know that seam manages the transactions using its conversations so I don't (?) have to worry about committing / rolling back the operations manually.
What I still don't get is how to extend EntityHome and EntityList objects beyond the ones generated by seam-gen to create DAOs that would provide me with the fine grained operations / joins I need in my application.
Am I missing something ?
I do know that seam manages the
transactions using its conversations
so I don't (?) have to worry about
committing / rolling back the
operations manually.
Yes, you dont need to worry about it, if there is an exception, seam will automatically do a rollback. The same thing for commit when there is no exception. I think you can control this manually too with seam annotations.
The DAO pattern is created when you need to separate the persistencie tier from business tier. EntityHome and EntityList are exactly the persistence tier. You dont need to create a dao.
The best path for whom are starting with seam is study the example that come with seam package .. see examples like dvdstore and booking. they are quite helpfull
Regards,
The other useful thing to is EntityQuery or HibernateEntityQuery. You specify your queries in XML and then can reference them as Seam components throughout your application. Although I use this much liked NamedQuery in JPA, I don't think this is a standard practice.
<framework:entity-query name="User_findByEmailAddress" ejbql="SELECT u FROM User u">
<framework:restriction>
<value>u.emailAddress = #{emailAddress}</value>
</framework:restriction>
</framework:entity-query>
Then in your Java code you can do:
#In
private EntityQuery<User> User_findByEmailAddress;
...
Contexts.getEventContext().set("emailAddress", emailAddress);
User user = User_findByEmailAddress.getSingleResult();
If you want to use this in your xhtml page, you can also use it there with built-in support for pagination.
Walter

Categories