2010-02-17 18 views
5

Uso di jsf 1.2, hibernate, richfaces 3.3.0GA e facelets.Impedire che lo stesso oggetto venga associato a due diverse sessioni in modalità ibernazione

Ho questo codice nel mio backing bean:

public List<Rater> getFreeRaters(){ 
    GP myGP = (GP) user; 
    update(myGP.getContract()); 
    ArrayList<Rater> raters = new ArrayList<Rater>(myGP.getContract().getRaters()); 
    ArrayList<Rater> selectedRaters = this.getSelectedRaters(); 
    raters.removeAll(selectedRaters); 
    return raters; 

} 

e questo codice per l'interfaccia utente:

<a4j:form id="gradersForm" ajaxSingle="true"> 
    <rich:listShuttle sourceValue="#{user.gradersTab.freeRaters}" id="gradersTab_listShuttle" 
    targetValue="#{user.gradersTab.selectedRaters}" var="rater" listsHeight="150" 
     sourceListWidth="130" targetListWidth="130" sourceCaptionLabel="Available Items" 
     targetCaptionLabel="Currently Active Items" > 
     <rich:column> 
      <h:outputText value="#{rater.username}"></h:outputText> 
     </rich:column> 
    </rich:listShuttle>   
    <a4j:commandButton value="Save"></a4j:commandButton> 

</a4j:form> 

Questo è il mio filtro sessione:

public class HibernateSessionRequestFilter implements Filter { 

private static Log log = LogFactory.getLog(HibernateSessionRequestFilter.class); 

private SessionFactory sf; 

public void doFilter(ServletRequest request, 
        ServletResponse response, 
        FilterChain chain) 
     throws IOException, ServletException { 
    HttpServletResponse resp= (HttpServletResponse) response; 
    try { 
     log.info("Starting a database transaction"); 
     Session session = sf.getCurrentSession(); 
     session.beginTransaction(); 

     // Call the next filter (continue request processing) 
     chain.doFilter(request, resp); 

     // Commit and cleanup 
     log.info("Committing the database transaction"); 

     session.getTransaction().commit(); 


    } catch (StaleObjectStateException staleEx) {... 

Il problema viene quando l'interfaccia utente viene nuovamente eseguita due o più volte contemporaneamente tramite AJAX. Essendo due richieste diverse, ognuna di esse riceve un Session e l'oggetto viene provato ad essere collegato ad entrambi contemporaneamente perché nessuno di loro ha tempo sufficiente per terminare e fare session.close(), quindi ibernare genera un'eccezione org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions

Qualche suggerimento per evitare che ciò accada? Grazie.

Aggiornamento: web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app id="WebApp_ID" version="2.5" 
xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web- app_2_5.xsd"> 
<display-name>eyeprevent</display-name> 
<context-param> 
<param-name>javax.faces.CONFIG_FILES</param-name> 
<param-value>/WEB-INF/faces-config.xml</param-value> 
</context-param> 
<context-param> 
<param-name>javax.faces.DEFAULT_SUFFIX</param-name> 
<param-value>.xhtml</param-value> 
</context-param> 
<context-param> 
<param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
<param-value>server</param-value> 
</context-param> 
<context-param> 
<param-name>facelets.LIBRARIES</param-name> 
<param-value>/WEB-INF/functions.taglib.xml</param-value> 
</context-param> 
<context-param> 
<param-name>org.richfaces.SKIN</param-name> 
<param-value>#{user.skin}</param-value> 
</context-param> 
<context-param> 
<param-name>org.richfaces.CONTROL_SKINNING</param-name> 
<param-value>enable</param-value> 
</context-param> 
<filter> 
<filter-name>HibernateFilter</filter-name> 
<filter-class>com.eyeprevent.util.HibernateSessionRequestFilter</filter-class> 
</filter> 
<filter> 
<display-name>RichFaces Filter</display-name> 
<filter-name>richfaces</filter-name> 
<filter-class>org.ajax4jsf.Filter</filter-class> 
</filter> 
<filter-mapping> 
<filter-name>HibernateFilter</filter-name> 
<url-pattern>/pages/*</url-pattern> 
</filter-mapping> 
<filter-mapping> 
<filter-name>HibernateFilter</filter-name> 
<url-pattern>/upload/*</url-pattern> 
</filter-mapping> 

<filter-mapping> 

<filter-name>richfaces</filter-name> 
<servlet-name>Faces Servlet</servlet-name> 
<dispatcher>REQUEST</dispatcher> 
<dispatcher>FORWARD</dispatcher> 
<dispatcher>INCLUDE</dispatcher> 
</filter-mapping> 
<listener> 
<listener-class>com.sun.faces.config.ConfigureListener</listener-class> 
</listener> 
<listener> 
<listener-class>com.eyeprevent.util.MySessionListener</listener-class> 
</listener> 
<servlet> 
<display-name>EPConnectServlet</display-name> 
<servlet-name>EPConnectServlet</servlet-name> 
<servlet-class>com.eyeprevent.servlets.EPConnectServlet</servlet-class> 
<init-param> 
<param-name>imagePath</param-name> 
<param-value>/home/pako/images</param-value> 
</init-param> 
<load-on-startup>1</load-on-startup> 
</servlet> 
<servlet> 
<servlet-name>imageServlet</servlet-name> 
<servlet-class>com.eyeprevent.servlets.ImageServlet</servlet-class> 
<init-param> 
<param-name>imagePath</param-name> 
<param-value>/home/pako/images</param-value> 
</init-param> 
</servlet> 
<servlet> 
<servlet-name>Faces Servlet</servlet-name> 
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
<load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
<servlet-name>EPConnectServlet</servlet-name> 
<url-pattern>/upload/EPConnectServlet</url-pattern> 
</servlet-mapping> 
<servlet-mapping> 
<servlet-name>imageServlet</servlet-name> 
<url-pattern>/image/*</url-pattern> 
</servlet-mapping> 
<servlet-mapping> 
<servlet-name>Faces Servlet</servlet-name> 
<url-pattern>*.xhtml</url-pattern> 
</servlet-mapping> 
<session-config> 
<session-timeout>0</session-timeout> 
</session-config> 
<welcome-file-list> 
<welcome-file>index.html</welcome-file> 
<welcome-file>index.xhtml</welcome-file> 
<welcome-file>index.htm</welcome-file> 
<welcome-file>index.jsp</welcome-file> 
<welcome-file>default.html</welcome-file> 
<welcome-file>default.htm</welcome-file> 
<welcome-file>default.jsp</welcome-file> 
<welcome-file>pages/login.xhtml</welcome-file> 
</welcome-file-list> 
<error-page> 
<error-code>404</error-code> 
<location>/pages/error.xhtml</location> 
</error-page> 
<error-page> 
<error-code>401</error-code> 
<location>/pages/unauthorized.xhtml</location> 
</error-page> 
<login-config> 
<auth-method>BASIC</auth-method> 
</login-config> 
</web-app> 
+0

la primavera è un'opzione? – Bozho

+0

No, ma so che la prossima volta lo prenderò in considerazione, a causa della "Mantieni la sessione aperta in vista", che è certamente utile. – pakore

+0

posso vedere la configurazione del servlet del tuo browser (da web.xml) – Bozho

risposta

2

A quanto pare utilizzando merge invece di update sembra risolvere il problema ...

Ricordate che merge restituisce la nuova istanza aggiornato, così si dovrebbe fare

myInstance = (myInstanceClass) Session.merge(myInstance); 
Problemi correlati