I'm making the maintenance of a app with Struts 1, Spring 3 and Hibernate 3.
I want join two services, but each service have 1 transaction. The solution that i am thinking is make 1 service with 1 transaction that include the two services. It's possible this?
-The transaction located in the DAO's.
*Service Expediente:
public void saveExpedienteCoactivo(CoaTExpc coaTExpc, Auditoria auditoria, String numeracionAutomaticaExpediente) throws Exception, BusinessException{
IExpedienteCoactivoDAO dao = (IExpedienteCoactivoDAO)getDao();
try{
//business rules
dao.saveExpedienteCoactivo(coaTExpc, numeracionAutomaticaExpediente);
catch{...}
}
*DAO Expediente:
public synchronized void saveExpedienteCoactivo(CoaTExpc coaTExpc, String numeracionAutomaticaExpediente) throws Exception {
Session sessionHibernate = this.getSessionFactory().getCurrentSession();
Savepoint savePoint = sessionHibernate.connection().setSavepoint();
try{
sessionHibernate.saveOrUpdate(coaTExpc);
sessionHibernate.connection().commit();
}catch(Exception e) {
sessionHibernate.connection().rollback(savePoint);
sessionHibernate.getTransaction().rollback();
System.out.println(this.getClass().getName()+", Error="+e);
throw new Exception(e);
}
}
*Service Resolucion:
public void saveResolucion(CoaTRcoa coaTRcoa, Auditoria auditoria) throws Exception, BusinessException{
IResolucionDAO dao = (IResolucionDAO)getDao();
try{
//business rules
dao.saveResolucion(coaTRcoa);
}catch{...}
}
*DAO Resolucion:
public synchronized void saveResolucion(CoaTRcoa coaTRcoa) throws Exception {
Session sessionHibernate = this.getSessionFactory().getCurrentSession();
Savepoint savePoint = sessionHibernate.connection().setSavepoint();
try{
//more code and sql here
sessionHibernate.saveOrUpdate(coaTRcoa);
//more code sql
sessionHibernate.connection().commit();
}catch(Exception e) {
sessionHibernate.connection().rollback(savePoint);
sessionHibernate.getTransaction().rollback();
System.out.println(this.getClass().getName()+", Error="+e);
throw new Exception(e);
}
}
*applicationContext.xml:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="mappingDirectoryLocations">
<list>
<value>classpath:gob/osinerg/spjc/configuracion/domain/mapping</value>
<value>classpath:gob/osinerg/spjc/notificaciones/domain/mapping</value>
<value>classpath:gob/osinerg/spjc/judicial/domain/mapping</value>
<value>classpath:gob/osinerg/spjc/coactiva/domain/mapping</value>
<value>classpath:gob/osinerg/spjc/common/domain/mapping</value>
<value>classpath:gob/osinerg/alfresco/domain/mapping</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
Now, It's possible this?
public class ServiceTransactionImp implements ServiceTransaction{
public void doTwoSaveTransaction(){
Session sessionHibernate = this.getSessionFactory().getCurrentSession();
Savepoint savePoint = sessionHibernate.connection().setSavepoint();
try{
serviceExpediente.saveExpedienteCoactivo(coaTExpc,auditoria,numeracionAutomaticaExpediente);
serviceResolucion.saveResolucion(coaTRcoa,auditoria);
sessionHibernate.connection().commit();
}catch(Exception e) {
sessionHibernate.connection().rollback(savePoint);
sessionHibernate.getTransaction().rollback();
System.out.println(this.getClass().getName()+", Error="+e);
throw new Exception(e);
}
}
I'm not sure if it works, because the session is distinct between the proceses and if the possible rollback of saveResolucion will affect to the service of saveExpedienteCoactivo as have a commit(); the idea is execute rollback to all the proceses.
Or any other solution?
Related
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="DataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
<prop key="org.hibernate.cache.ehcache.configurationResourceName">classpath:hibernate-ehcache.xml</prop>
<prop key="cache.provider_class">${cache.provider_class}</prop>
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
</props>
</property>
</bean>
<!-- Hibernate template for hibernateSessionFactory -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Transaction Manager for hibernateSessionFactory -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="DataSource" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Above is the Hibernate config for the spring boot application. We have addition added the following c3po config. But still the connection pool is getting maxed out.
<bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClassName}"></property name>
<property name="jdbcUrl" value="${ondot.jdbc.url}"></property name>
<property name="user" value="${jdbc.user}"></property name>
<property name="password" value="${jdbc.password}"></property name>
<property name="initialPoolSize" value="${initialPoolSize}" /></property name>
<property name="minPoolSize" value="${minPoolSize}"></property name>
<property name="maxPoolSize" value="${maxPoolSize}"></property name>
<property name="acquireIncrement" value="${acquireIncrement}"></property name>
<property name="maxStatements" value="${maxStatements}"></property name>
<property name="acquireRetryAttempts" value="${acquireRetryAttempts}"></property name>
<property name="acquireRetryDelay" value="${acquireRetryDelay}"> </property name>
<property name="breakAfterAcquireFailure"
value="${breakAfterAcquireFailure}"></property name>
<property name="maxIdleTime" value="${maxIdleTime}"> </property name>
and following is the property file:
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
hibernate.generate_statistics=true
cache.provider_class=org.hibernate.cache.EhCacheProvider
initialPoolSize=5
minPoolSize=100
maxPoolSize=250
acquireIncrement=5
maxStatements=100
acquireRetryAttempts=10
acquireRetryDelay=1000
breakAfterAcquireFailure=false
maxIdleTime=1800
The session factory is autowired and a simple code with Open and close session is written.
public class BasicAunthenticationImpl {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory()
{
return sessionFactory;
}
public static void setSessionFactory(SessionFactory sessionFactory)
{
BasicAunthenticationImpl.sessionFactory = sessionFactory;
}
}
public class Module1
{
#Autowired
private SessionFactory sessionFactory;
private Session session = null;
#Override
public void process(List<RoutableModuleData> routableProcessObjects)
throws OndotException
{
try
{
session = sessionFactory.openSession();
session.flush();
canonicalMessage =
lookupprocesser.processInput(canonicalMessage,
Constants.L1_LOOKUP_CACHE, session);
}
catch (Exception Ex)
{
}
finally
{
if (session != null && session.isOpen()){
session.close();
}
}
}
}
public class Lookupprocesser{
public CanonicalMessage processInput(CanonicalMessage canonicalMessage,
String cacheLookup, Session session) throws DataInsightsCommonException
{
lookupSearchForL1(canonicalMessage, session, cacheLookup);
return canonicalMessage;
}
}
public class Query{
public List<TerminalData> searchByMatchKey1AndMatchKey2(Session
session, String matchKey1, String matchKey2) throws
DataInsightsCommonException
{
Query query;
List<Data> t = null;
query = session.createQuery("from Data as odt where odt.Key1 is
null and odt.Key2 = :Key2");
query.setParameter(Constants.KEY2, Key2);
query.setCacheable(true);
terminals = (List<Data>) query.list();
return (null != t && !t.isEmpty()) ? t : null;
}
}
The Session object is shared among all classes and object, I edited the code below , BasicAuth class creates the SessionFactory
The Module1 will call LookupProcessor and which will call the query class. We are closing the session on the Module1.
#Repository
public class Init {
public static void main(String[] args) {
Init init = new Init();
init.addUser(init.getSessionFactory());
}
private SessionFactory getSessionFactory() {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "Spring_Hibernate.xml" });
SessionFactory sf = (SessionFactory) context.getBean("sessionFactory");
return sf;
}
#Transactional
private void addUser(SessionFactory sf) {
Session session = sf.getCurrentSession();
User user = new User();
user.setName("123");
session.save(user);
session.close();
sf.close();
}
}
xml:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.warmmer.bean" />
<property name="hibernateProperties">
<!-- <value> hibernate.dialect=org.hibernate.dialect.HSQLDialect </value> -->
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
err:
INFO: Using DataSource [org.apache.commons.dbcp.BasicDataSource#6098b14d] of Hibernate SessionFactory for HibernateTransactionManager
Exception in thread "main" org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
If:
hibernate.current_session_context_class set 'thread'
then :save is not valid without active transaction
what should I do please?
You are not creating your "Init" object within the spring context, so spring would never get a chance to wrap a proxy around the method with the annotation that will manage the transaction
Try changing your class to...
package my.pkg;
// Imports etc
#Repository
public class Init {
#Autowired
private SessionFactory sessionFactory;
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "Spring_Hibernate.xml" });
Init init = context.getBean(Init.class);
init.addUser();
}
#Transactional
private void addUser() {
Session session = sessionFactory.getCurrentSession();
User user = new User();
user.setName("123");
session.save(user);
// session.close(); DON'T NEED THESE!
// sf.close();
}
}
Now you might need to add the following to your beans file so that it finds your repository...
<context:component-scan base-package="my.pkg"/>
I have a Using c3p0 0.9.1.2 , hibernate 3.2.1.ga and spring 2.5.5. The problem is the database connection doesn't close itself. Here are the logs :
[22 mars 2012 12:29:56,091] DEBUG com.mchange.v2.resourcepool.BasicResourcePool ["http-apr-8080"-exec-4] acquire test -- pool is already maxed out. [managed: 20; max: 20]
[22 mars 2012 12:29:56,091] DEBUG com.mchange.v2.resourcepool.BasicResourcePool ["http-apr-8080"-exec-4] awaitAvailable(): com.mchange.v2.c3p0.impl.NewPooledConnection#15cc604
[22 mars 2012 12:29:56,091] DEBUG com.mchange.v2.resourcepool.BasicResourcePool ["http-apr-8080"-exec-4] trace com.mchange.v2.resourcepool.BasicResourcePool#6b0524 [managed: 20, unused: 0, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection#15cc604)
Here's the datasource configuration :
<!-- Local DataSource that works in any environment -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${database.driver}"/>
<property name="jdbcUrl" value="${database.url}"/>
<property name="user" value="${database.user}"/>
<property name="password" value="${database.password}"/>
<!--<property name="connectionCustomizerClassName" value="org.xxx.webapp.common.persistence.WatchConnectionCustomizer"/>-->
<property name="maxStatements" value="500"/>
<property name="maxIdleTime" value="1800"/>
<property name="maxPoolSize" value="100"/>
<property name="minPoolSize" value="2"/>
<property name="initialPoolSize" value="2"/>
<property name="acquireIncrement" value="3"/>
<property name="idleConnectionTestPeriod" value="3000"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.connection.autocommit">${hibernate.connection.autocommit}</prop>
<prop key="hibernate.transaction.auto_close_session">${hibernate.transaction.auto_close_session}</prop>
<prop key="hibernate.connection.release_mode">${hibernate.connection.release_mode}</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">${hibernate.bytecode.use_reflection_optimizer}</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
...
</list>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
Here's our generic Dao
public class GenericDAO<T, PK extends Serializable> extends HibernateDaoSupport
implements IGenericDAO<T, PK> {
private Class<T> clazz;
private Logger logger = Logger.getLogger(GenericDAO.class);
private static Session session;
public GenericDAO(Class<T> clazz) {
this.clazz = clazz;
}
public void refresh(T instanceToRefresh) throws DataAccessException {
getHibernateTemplate().refresh(instanceToRefresh);
//getCurrentSession().refresh(instanceToRefresh);
}
public void saveOrUpdate(T instanceToSaveOrUpdate)
throws DataAccessException {
//getCurrentSession().saveOrUpdate(instanceToSaveOrUpdate);
getHibernateTemplate().saveOrUpdate(instanceToSaveOrUpdate);
}
public void persist(T instanceToPersist) throws DataAccessException {
getHibernateTemplate().persist(instanceToPersist);
//getCurrentSession().persist(instanceToPersist);
}
#SuppressWarnings("unchecked")
public T merge(T instanceToMerge) throws DataAccessException {
T instanceMerged = (T) getHibernateTemplate().merge(instanceToMerge);
//T instanceMerged = (T) getCurrentSession().merge(instanceToMerge);
return instanceMerged;
}
#SuppressWarnings("unchecked")
public PK save(T newInstance) throws DataAccessException {
return (PK) getHibernateTemplate().save(newInstance);
//return (PK) getCurrentSession().save(newInstance);
}
public void delete(T persistentObject) throws DataAccessException {
getHibernateTemplate().delete(persistentObject);
//getCurrentSession().delete(persistentObject);
}
#SuppressWarnings("unchecked")
public T load(PK id) {
return (T) getHibernateTemplate().get(clazz, id);
//return (T) getCurrentSession().get(clazz, id);
}
public void update(T transientObject) throws DataAccessException {
//getCurrentSession().update(transientObject);
getHibernateTemplate().update(transientObject);
}
#SuppressWarnings("unchecked")
public List<T> loadAll() throws DataAccessException {
//Session session = this.getCurrentSession();
//return session.createQuery("from " + clazz.getName()).list();
return getHibernateTemplate().loadAll(clazz);
}
}
Thanks in advance.
Normally, the connection is automatically closed by hibernate. However, a few things to note:
long-running transactions may occupy a connection
improper session management may mean you don't close your session, which in turn means the connection remains in use
The typical setup when using spring is to annotate your service methods with #Transactional. That way spring will manage your transactions and sessions.
We have used the following line in the dispatcher-servlet.xml file and database physical connections are now closing.
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/>
<prop key="hibernate.hbm2ddl.auto">create</prop> creates a new database schema and <prop key="hibernate.hbm2ddl.auto">update</prop> create if it is not exists and update existing database schema. If I want to check whether database schema exists or not and depending on that a database schema will be created, how can I achieve this. Currently the configuration of my applicationContext.xml is:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>info.ems.models.User</value>
<value>info.ems.models.Role</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<bean id="dao" class="info.ems.hibernate.HibernateEMSDao" init-method="createSchema">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
And the HibernateEMSDao.java:
public class HibernateEMSDao implements EMSDao {
private final Logger logger = LoggerFactory.getLogger(getClass());
private HibernateTemplate hibernateTemplate;
public void setSessionFactory(SessionFactory sessionFactory) {
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}
public void saveUser(User user) {
hibernateTemplate.saveOrUpdate(user);
}
public List<User> listUser() {
return hibernateTemplate.find("from User");
}
public void createSchema() {
logger.info("inserting default admin user into database");
User admin = new User();
admin.setUsername("admin");
admin.setName("Admin");
admin.setEmail("admin");
admin.setPassword("21232f297a57a5a743894a0e4a801fc3");
saveUser(admin);
logger.info("Admin inserted into database");
try {
System.out.println(listUser().get(0).getId());
} catch (Exception e) {
logger.error("===================Error================");
}
}
}
It is working. What configuration will help me to gain this?
Something like:
Check an user with id=1 exists
If not create the schema
Thanks and regards.
You could disable the hibernate.hbm2ddl.auto option, check the conditions (probably using plain JDBC) and call (or don't) the create method of the SchemaExport class. This would be done in your application's initialization code (a ServletContextListener in case you are working with a web app).
An example on how to use the SchemaExport class:
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass(info.ems.models.User.class);
config.addAnnotatedClass(info.ems.models.Role.class);
config.configure();
new SchemaExport(config).create(true, true);
I am using OpenSessionInViewFilter, Spring, and Hibernate for data access. When I commit a data record, my view results do not show the commited record using lazy loading. My session factory configuration looks like this:
<bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
<property name="poolPreparedStatements" value="true" />
<property name="defaultAutoCommit" value="true" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dbcpDataSource" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dbcpDataSource" />
<property name="annotatedClasses">
<list>
<value>or.pac.Address</value>
<value>or.pac.Customer</value>
<value>or.pac.Documents</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.auto_close_session">true</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.max_fetch_depth">4</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="locator" class="cc.SessionLocator">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
OpenSessionInViewFilter configuration in the web.xml looks exactly like this:
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
To obtain a session for my DAO I have below SessionLocator class which opens session for me;
public class SessionLocator{
public static final ThreadLocal session = new ThreadLocal();
private static SessionLocator me;
static {
try {
me = new SessionLocator();
} catch (Exception e) {
e.printStackTrace();
}
}
private SessionLocator() throws HibernateException, JDBCException {
}
public static Session currentSession() throws Exception {
Session s = (Session) session.get();
if (s != null) {
s.setCacheMode(CacheMode.REFRESH);
}
if (s == null) {
synchronized SessionLocator{
s =openSession();
}
session.set(s);
}
return s;
}
public void setSessionFactory(SessionFactory sessionFactory) {
PersistenceManager.sessionFactory = sessionFactory;
}
public static Session openSession() {
Session session = SessionFactoryUtils.doGetSession(sessionFactory, true);
return session;
}
private static SessionFactory sessionFactory;
}
And then in My DAO service I do Save and Update like this:
public boolean upsert(Object d) {
try {
SessionLocator.currentSession().saveOrUpdate(d);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
When I call upsert(), I can see the record on the table, but the updated value does not show up in my view during lazy loading. Do any one knows why the hibernate cache is not refreshed with the current record?
This issue was resolved by removing below line from openSessionInViewFilter config:
<dispatcher>FORWARD</dispatcher>
And annotate the DAO Service with #Transactional annotation
#Transactional
public boolean upsert(Object d) {
try {
SessionLocator.currentSession().saveOrUpdate(d);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}