I'm working on a system where things can and will change outside of JPA, so I need a new session for every request, but my JavaEE app deployed into TomEE persists sessions between requests, resulting in entities that are cached when they've since been updated somewhere outside of the app.
I attempted to create a cfg.xml and get the session factory that way, but was just met with exceptions. I also attempted to unwrap the entity manager class to get the factory that way, but got an exception saying the class couldn't be unwrapped. I feel like this may be something to do with how TomEE and Hibernate interact. Are there issues with my current setup. Or am I trying to implement session-per-request wrong,
The problem that you have is not with the session, it is related with the session cache, so what you can do is invalidate your session cache:
session.refresh(entity)
then hibernate will compare database data and entity object data if there are differences then it will execute again an sql query.
session.clear()
will remove everything from the session cache, so you will not get old data.
Related
I'm implementing database access to a Postgres database using WebLogic 12c, JPA 2.2 and Hibernate 5.
I finally solved the problem, where I couldn't make 2 separate request from the database with separate datasources, users, etc. by switching Global Transactions off.
Now my problem is that whatever I do, the entities I'd like to save are not actually saved to the database. I have the #Transactional on all methods where inserting happens, but nothing gets written to the DB.
I went ahead and created an interceptor for Hibernate, which logs out when and what transaction gets commited. I see that something gets commited, but the transaction I get from the method parameter is null.
I'm sure I'm overlooking something obvious, but I can't for the life of me get to know what it is
I Managed to find an error (Bug) in
https://github.com/spring-projects/spring-session
Due to the fact that the project is poorly configured.
I set up that all sessions are saved in the database through the config: #EnableJdbcHttpSession in Mysql (MariaDB).
The trouble is that the filter is one for all and any request to the front ... for example, give the statics (picture, css, etc.) - it has its own session key and also climbs into the database.
Everyone getting the picture.
Any request from the front in which there is a session and the cuckolds goes to the Mysql.
Requests that do not need to go to the database go there.
This is a large number of SELECT .... UPDATE ... table calls
SPRING_SESSION
SPRING_SESSION_ATTRIBUTES
How would this error be described to the developers?
How to configured spring session with EnableJdbcHttpSession and filter ?
Only business request went to the database ?
I'm working on a REST webservice that uses hibernate as an OR Mapper. I recently upgraded hibernate from 3.2 to 4.3 and got an error I described here. Basically my transaction got rolled back somewhere and then I got an error when I wanted to use that session again (which is correct hibernate behavior).
I think I figured out why I got that error. It is because when I receive the request a long session is started. This session also opens a transaction that will be open for a longer period of time. Besides this long running session/transaction also some small session/transaction should be opened on the same thread. As far as I found out, all sessions get the same UserTransaction to work with and since the small transactions commit and rollback this transaction I run in the error described in my other post.
Since I'm working with a huge code base it is that easy to change the code so that all that side session run in a different thread (in case that would help) or to refactor the whole service so that only one transaction can be open at any time.
Actual Question starts here
Is there any possibility to start multiple simultaneous sessions/transactions in one Thread? If so, what would I have to do, to tell hibernate to do that? If this is not possible what way of accomplishing a similar behavior would you suggest?
Code snippet I use to create the sessions
Session session = sessionFactory.openSession();
CustomSessionWrapper dpSession = new CustomSessionWrapper(session, this);
if (!session.isClosed() && !session.getTransaction().isActive()) {
session.beginTransaction();
}
The code worked before I upgraded hibernate so the problem should not be in the CustomSessionWrapper or any other custom class.
Thanks a lot in advance!
Open at the begin of the http request and close at the end and each http request is treated in a separated thread?
Maybe saving all session in a HashMap and access it statically?
Any information which explains how hibernate sessions work (or what they really are) are helpful.
If at the beginning of request/end of request means the http Request, then this is usually done by a servlet filter which opens/closes session for you. This design pattern is called OpenSessionInView (Filter). You can get details here.
This pattern is useful only if you application is rendered in same JVM where Hibernate Session exists. If Your data access tier resides on different JVM than your view rendering tier, you will have to (eagerly) fetch all the required model beans before dispatching the request for rendering of the view .
If you are using spring (or EJB3), you can get the Session (EntityManager) injected in your Data Access classes so you wont need to manually work on Opening and closing the session.
Ideally, you should not need to manually open/close session/transaction (because it leaves chances of missing out a session.close() or tx.commit() and the likes). Instead use the container provided JPA entitymanager or use spring to manage it for you.
There are multiple patterns of using the session, but the most common and usually the proper one is to open and close it on each request (=thread=unit of work)
In a JavaEE environment you would normally make use of JPA. So use hibernate through the EntityManager, which can be injected in components (like EJBs or cdi managed beans) with #PersistenceContext
usually a session is open when accessing data store is needed (e.g. transaction begins). When to close it has different patterns and approaches. you could keep the session open in views (jsps). but you don't have to do that.
e.g. one of our project doesn't allow to use opensessionInView filter. So the session was closed after transaction ended. All data (Value objects basically) need to send to view were loaded before dispatching.
I am using Turbine 2.3.2 with Hibernate 3. My problem is that the Hibernate session is not active when my (Velocity 1.6.4) template is executed, and I am accessing data from the database for which Hibernate needs lazy initialization. Therefore I get a LazyInitializationException - no Session error.
Since I want my Hibernate session to be alive when a velocity template executes I would like to have a class to execute after and before the Velocity template. This way I could open and close my Hibernate session at one place. (Disabling lazy initialization in Hibernate is not an option for me). Are there any possibilities related or not to Turbine to write a kind of listener or a filter (I am not sure how to call it) that would execute right before and after a Velocity template has been executed? Or maybe the servlet container could filter requests .... What option would you recommend?
Try looking at the Spring OpenSessionInViewFilter. It opens the Hibernate Session and assigns it to a threadlocal. That way, you can pick it up in your data access layer and use it.
Open Session in View is not a clean solution. You can configure in your criteria (if you use it) which association paths Hibernate has to eagerly fetch.
If you use HQL, just "touch" the association while the session is still open.
Your question seems to be about the (in)famous Open Session In View (OSIV) pattern.
Have a look at the Open Session in View page on the JBoss wiki, you'll find a filter based implementation (non Spring based).