2010-11-29 15 views
2

J'utilise OpenSessionInViewFilter, Spring, et Hibernate pour l'accès aux données. Lorsque je valide un enregistrement de données, mes résultats d'affichage n'affichent pas l'enregistrement validé en utilisant un chargement paresseux. Ma configuration usine de la session ressemble à ceci:Les enregistrements chargés ne sont pas à jour. Utiliser Hibernate et OpenSessionInViewFilter

<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 dans le web.xml ressemble exactement ceci:

<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> 

Pour obtenir une session pour mon DAO je dessous de la classe SessionLocator ce qui ouvre la session pour moi;

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; 

}

Et puis dans Mon service OAC Je ne sauvegardons et mise à jour comme ceci:

public boolean upsert(Object d) { 
    try { 
     SessionLocator.currentSession().saveOrUpdate(d); 
       } catch (Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
    return true; 
} 

Quand j'appelle upsert(), je peux voir le dossier sur la table, mais la valeur mise à jour n'apparaît pas dans ma vue pendant le chargement paresseux. Est-ce que quelqu'un sait pourquoi le cache d'hibernation n'est pas actualisé avec l'enregistrement en cours?

Répondre

1

Ce problème a été résolu en supprimant la ligne ci-dessous de config openSessionInViewFilter:

<dispatcher>FORWARD</dispatcher> 

Et annoter le service DAO avec l'annotation @Transactional

@Transactional 
public boolean upsert(Object d) { 
try { 
    SessionLocator.currentSession().saveOrUpdate(d); 

    } catch (Exception e) { 

    e.printStackTrace(); 
    return false; 
    } 
    return true; 
    }