I am taking the LazyInitializationException error when because in myController when I read the Lazy collections session is already closed. Is there any way to get it open as long as there is a request? As OpenSessionInView? What would be the best way?
I'm using the version of Spring Boot 1.3.0
You need use the "open session in view" to keep the session open after the end of the transaction.
see OpenSessionInViewFilter or OpenEntityManagerInViewFilter for JPA
imho it's better than extending the scope of the transaction to your controller.
If you're using a jackson/hibernate combination you can register the jackson-datatype-hibernate module, and tweak the Feature.FORCE_LAZY_LOADING property to your liking. The default is false means that only already fetched properties will be serialized. Changing to true will force initialization of the lazy properties
Related
I am using the java Batch (JSR-352), it is possible to work with a session bean inside it? I needed to have a Bean with #SessionScope annotation, to catch some information in it, that to differentiate the type of User that is running the batch process.
It's possivel use a Session Context CDI inside the specification ? If is possible how is the best pratice
In general, the session isn't going to propagate from the thread starting the job via JobOperator to the execution thread. I don't recall if this is under discussion in the CDI specification still or a settled matter, but for now you can't.
I got below exception when I used session.getCurrentSession().
I have mentioned
hibernate.current_session_context_class: managed
org.hibernate.HibernateException: No session currently bound to execution context
at org.hibernate.context.internal.ManagedSessionContext.currentSession(ManagedSessionContext.java:75)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at io.dropwizard.hibernate.AbstractDAO.currentSession(AbstractDAO.java:36)
at io.dropwizard.hibernate.AbstractDAO.persist(AbstractDAO.java:149)
I use this with dropwizard. Can anyone help me to solve this?
If you are using Dropwizard Hibernate. You need to add #UnitOfWork annotation to your Resource method. More info within dropwizard manual, hibernate chapter.
Can you try with : session.openSession() - It tell hibernate to always opens a new session and you have to close once you are done with the operations. With session.getCurrentSession(), hibernate returns a session bound to a context that you don't need to close and only need to set the hibernate.current_session_context_class to thread.
You can also configure session with SpringSessionContext, if your application is Spring based.
Edit your hibernate-cfg.xml with below line:
hibernate.current_session_context_class=org.springframework.orm.hibernate3.SpringSessionContext
What above line will do?
Making session context class as "org.springframework.orm.hibernate3.SpringSessionContext
", Hibernate will assume it is executing inside of a Spring transactional context (i.e. through a Spring transactional aspect) and Spring will now manage your transaction for you. However if you call getCurrentSession() outside of such a context, Hibernate will throw an exception complaining that no Session is bound to the thread.
I am trying to enable my web application to use one (MySQL) schema per user.
I am using Spring with JPA along with Hibernate.
Is the Hibernate Multi-tenancy concept relevant?
The way I am trying to do it is
(a) have a EntityManagerFactory per HTTPSession and
(b) set the schema in it at login.
I have figured out how to do (b), but I still have issues doing (a).
I tried putting #Scope(WebApplicationContext.SCOPE_SESSION), but what about the global EntityManagerFactory?
Any help?
You can implement your own ConnectionProvider and there make extra settings.
But I think that you have large problems with the architecture your application if you want to do one schema per user.
UPD1
If you use spring. You can try to declare a bean with own impl of ConnectionProvider in Session scope.
But there is a big problem. Hibernate make the ConnectionProvider. It means that you have to impl own ServiceRegistry (with working through Spring) and override StandardServiceRegistryBuilder, and impl EntityManagerFactoryBuilder (based on EntityManagerFactoryBuilderImpl but with your StandardServiceRegistryBuilder).
When new session have been created it'll use ConnectionProvider to create the connection (Probably you'll have to override some classes).
This is really not suggested.. This will harm you later, you can't do differnt schema for diffrent user. You can always create you own properties to the connection..
Configuration cfg = new Configuration();
cfg.configure();
System.setProperty("hibernate.connection.password",pass);
System.setProperty("hibernate.connection.username",usr);
System.setProperty("hibernate.connection.driver_class", driver_class);
System.setProperty("hibernate.connection.url", driver_url);
System.setProperty("hibernate.dialect", dialect);
// etc, etc, for all properties
cfg.setProperties(System.getProperties());
sessionFactory = cfg.buildSessionFactory();
It can be something like that.. But this is WRONG!
I have a Spring 3 application using openJPA as persistence management, following section works fine in STS/Tomcat
#Transactional
createBalance(){
.....
Balance balance = new SummaryBalance();
balance.setName(name);
balance.setCurrency(currency);
balance.setClosingTimestamp(closingTime);
balance.setStatus(BalanceStatus.OPEN);
balance.persist(); // persist !!
......
balance.setCloseAmount(amount);
balance.setLastUpdateTimestamp(now);
}
However, when deploying same code in websphere 7, the closeAmount and lastUpdate does not update(both fields in DB didn't get update but from log both field can return values by their getter) then show up as null, but changes to other fields before persist() do take effect when the method finished. So I bet when the method finishing WS didn't flush the changes towards these fields.
I thought the JPA(regardless of vendor) should keep the balance entity object managed after persist() and flush the object after the method is finished with later changes. Turns out Websphere 7 doesn't make it. Even I put a merge() method
balance.setCloseAmount(amount);
balance.setLastUpdateTimestamp(now);
balance.merge();
still does not help.
Questions:
OpenJPA has already been included as dependencies in the deployment, but why still websphere need to involve with the JPA management?
How to solve the problem?
Thanks in advance.
I'm not sure that this exactly answers your question, but I think you should do some reconfiguration to use WebSphere capabilities, please check Spring 3.1 documentation
11.8.1 IBM WebSphere
On WebSphere 6.1.0.9 and above, the recommended Spring JTA transaction
manager to use is WebSphereUowTransactionManager. This special adapter
leverages IBM's UOWManager API, which is available in WebSphere
Application Server 6.0.2.19 and later and 6.1.0.9 and later. With this
adapter, Spring-driven transaction suspension (suspend/resume as
initiated by PROPAGATION_REQUIRES_NEW) is officially supported by IBM!
and
11.9.1 Use of the wrong transaction manager for a specific DataSource
Use the correct PlatformTransactionManager implementation based on
your choice of transactional technologies and requirements. Used
properly, the Spring Framework merely provides a straightforward and
portable abstraction. If you are using global transactions, you must
use the org.springframework.transaction.jta.JtaTransactionManager
class (or an application server-specific subclass of it) for all your
transactional operations. Otherwise the transaction infrastructure
attempts to perform local transactions on resources such as container
DataSource instances. Such local transactions do not make sense, and a
good application server treats them as errors.
Figure out a solution myself with guess work. Simply just place the persist() by the end of the whole method body.
#Transactional
createBalance(){
.....
Balance balance = new SummaryBalance();
balance.setName(name);
balance.setCurrency(currency);
balance.setClosingTimestamp(closingTime);
balance.setStatus(BalanceStatus.OPEN);
......
balance.setCloseAmount(amount);
balance.setLastUpdateTimestamp(now);
......
balance.persist(); // persist !!
}
That can make sure every fields are set before the method finished.
Both merge() and explicit flush() won't do the job but only with above compromise. Still not quite sure about the official work around....
I will keep this thread open for any new thinking come in :)
I am currently using version 3.3 of hibernate.
Currently the setting of hibernate is such that it will autocommit after each persistence of individual object.
I want to wrap a transaction around it, so it will only commit after end of a batch.
The code is in question:
getHibernateTemplate().saveOrUpdateAll(collectionOfObject);
I have consulted the documentation here, but want to see if there is alternative (other than rewriting it to use HSQL)
EDIT
My goal is to have a transaction around a bunch of insert. Currently it is auto-commit per insert
If you want to use transaction management in Spring read here on how to do it.
Also, Use should not be using HibernateTemplate use the Session object instead as below.
sessionFactory = getHibernateTemplate().getSessionFactory();
Session session = sessionFactory.getCurrentSession();
for (Bean bean : listBeans) {
session.saveOrUpdate(bean );
}
As there is no way to save the collection at one shot in session. This will commit the data after method exit.