2

Basic example to showcase my problem :

  1. Two users A and B connect to the JSF web app from different browsers, and the welcoming page shows their documents and a search panel.
  2. Both of them want to search for documents using a word or sentence.
  3. (for instance) A wants to search for the word "sheets" and B wants to search for the word "virus".
  4. They write down the word in the form input and they simultaneously submit the form.
  5. A gets the result of her search, while B suddenly gets also the same result as A with a word he didn't type which is "sheets".

Here's my managedBean :

@ManagedBean
@RequestScoped
public class DocumentController implements Serializable {

private String motSearch= null;
private boolean searching = false;
private boolean rechercheStructure = true;
private DocumentDao dao; //Dependency injection with Spring

public void onload(Utilisateur user)
{
    if(!searching)
    {
        motSearch = null;

        documentsListForConnectedUser(user);
    }
    else{
        search(user);
    }
}

public void search(Utilisateur user)
{
    documentsListForConnectedUser(user);// getting documents list from database

    searching = true;

    List<Document> list = new ArrayList<>();
    list.addAll(user.getDocuments());

    user.setDocuments(new ArrayList<>());

    //...

    if(motSearch != null && !motSearch.isEmpty())
    {
        LOGGER.info("motSearch : "+motSearch.toLowerCase());

        List<Document> docs = user.getDocuments();

        for(Document doc : list)
        {
            if(!docs.contains(doc) && (doc.getNom().toLowerCase().contains(motSearch.toLowerCase()) ||
                    doc.getDescription().toLowerCase().contains(motSearch.toLowerCase()) ||
                    doc.getTheme().toLowerCase().contains(motSearch.toLowerCase()) ||
                    doc.getKeywords().contains(motSearch.toLowerCase())))
            {
                docs.add(doc);
            }
        }

        docs = filter(docs);

        if(docs.size() == 0)
        {
            user.setDocuments(null);
        }
    }
    else
    {
        user.setDocuments(list);
    }

}
}

The JSF page ListeDocuments.xhtml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:f="http://xmlns.jcp.org/jsf/core"
  xmlns:p="http://primefaces.org/ui">
<h:head>
<f:metadata>
    <f:viewParam name="searching" value="#{documentController.searching}" />
    <f:viewParam name="structure" value="#{documentController.rechercheStructure}"/>
    <f:viewParam name="q" value="#{documentController.motSearch}"/>
    <f:viewAction action="#{documentController.onload(user)}"/>
</f:metadata>
</h:head>

<h:body>
<h:form id="myForm" prependId="false" >
        <h:inputHidden value="true" id="searching"/>

        <div class="center">
            <h:selectOneRadio converter="javax.faces.Boolean"
                              value="#{documentController.rechercheStructure}" onchange="check()" id="structure">
                <f:selectItem itemLabel="Recherche structurée" itemValue="true" />
                <f:selectItem itemLabel="Recherche plein texte" itemValue="false" />
            </h:selectOneRadio>
        </div>

        <div class="row">
            <div class="input-field col s12 m7 l8">
                <p:inputTextarea styleClass="materialize-textarea" id="q" value="#{documentController.motSearch}"/>
                <label for="q">Mot/phrase à chercher</label>
            </div>
        </div>

        <p:commandButton styleClass="btn blue-grey" update=":table"
                         type="submit" value="Chercher"
                         action="ListeDocuments?faces-redirect=true&amp;includeViewParams=true" />
</h:form>

<p:dataTable id="table" tableStyleClass="hoverable striped" rows="10" paginator="true"
             value="#{user.documents}" var="doc"
             paginatorPosition="bottom" paginatorAlwaysVisible="false" styleClass="borderless">

    <!--Columns-->

</p:dataTable>

</h:body>

</html>

My web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd"
     id="WebApp_ID" version="3.0">

<welcome-file-list>
    <welcome-file>index.xhtml</welcome-file>
</welcome-file-list>

<session-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>

<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

<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>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

<error-page>
    <error-code>404</error-code>
    <location>/404.html</location>
</error-page>

<error-page>
<error-code>500</error-code>
<location>/serverError.xhtml</location>
</error-page>

<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/serverError.xhtml</location>
</error-page>

<!-- Add Support for Spring -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>

<context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>none</param-value>
</context-param>

<context-param>
    <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
</context-param>

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

</web-app>

faces-config.xml file :

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

<application>
    <el-resolver>
        org.springframework.web.jsf.el.SpringBeanFacesELResolver
    </el-resolver>
</application>

PS : I'm using :

  1. Mojarra 2.2.9 JSF implementation.
  2. Apache Tomcat 7 server with Servlet 3.0.
  3. Spring but I only use it to inject interface implementations like DAOs.
  4. Hibernate 4/JPA as ORM.
  5. Since I needed to use Omnifaces 2.4 library for its converters I was obliged to integrate CDI (weld-servlet-2.3.5 final) and create an empty beans.xml (guidelines from BalusC blog), and I don't use any of its annotations in my managedBeans.
  6. The only annotations I use are @ManagedBean and @xxxxScoped from javax.faces.bean and sometimes @PostConstruct.
  7. Finally Primefaces 6.0

Any help is appreciated !

Sam
  • 605
  • 9
  • 19
  • Make sure you aren't mixing up **annotations** `@Named` = CDI, `@scope("...")` = Spring, and deppending on if the package is *javax.faces.bean.* for Which is whould be accompanied by `@ManagedBean` OR *javax.enterprise.context.* in which case it should be accompanied by `@Named` I have an app working with CDI beans that also uses search quereis but this behaviour doesn''t seem to be my case... so maybe just double check your packages/annotations ? Its hard enough to sometimes mix Spring-JSF so make sure you aren't mixing Spring-JSF-CDI beans right. – Esteban Rincon Aug 29 '16 at 21:07
  • I only use JSF annotations `@xxxxScoped`,`@ManagedBean` from `javax.faces.bean ` package. , I don't use `@Named` or `@Scoped("...")` . – Sam Aug 29 '16 at 21:20
  • @estebanrincon , In your app , can you please tell what did you use, all these annotations are confusing me. – Sam Aug 29 '16 at 21:50
  • Well there are a lot of ways you can perform this taks (search with ajax) What are you using Spring for ? And what I mean is why did you choose to combine Spring and JSF ? second of all, if you are still a bit confused with the annotations, don't you think you should stick to one technology until you grasp their concept and then start mixing them ? anyways here's a link that explains in great detail how to choose the proper bean scope for a specific task: http://stackoverflow.com/a/7031941/2940051 – Esteban Rincon Aug 29 '16 at 22:08
  • In my app I just used CDI beans with JSF 2.2. Actually not even primefaces was used, just the plain `` tag functionality, the rest was pretty simple, use the `event="keyup"` to call a Bean function to access a *service* that would search for a "string" LIKE ... It was very simple but did the work. Hope this helps – Esteban Rincon Aug 29 '16 at 22:13
  • It was my boss that forced me to use these technologies, and it's my first project working with JSF. I use Spring for injecting interface implementations like Dao Implementations and service implementations, not for annotating managed beans, and I don't use CDI annotations. I only stick to JSF annotations from `javax.faces.bean` package. – Sam Aug 29 '16 at 22:34
  • my search form has 10 inputs, I only showed you one to be brief, so calling the search method on a each keyup is a little bit expensive. Excuse me, but correct me if I'm wrong, I assume you used a session scoped bean with the annotations `@Named` `@SessionScoped` , right? ... bear with me a little bit please ! – Sam Aug 29 '16 at 22:41
  • Yes, but remember that for you to be able to use CDI you need the weld implementation and also make sure that its `javax.enterprise.context.SessionScoped` not `javax.faces.bean.SessionScoped` – Esteban Rincon Aug 29 '16 at 23:05
  • BTW what server are you using ? and also its best if you use CDI instead of JSF managed beans – Esteban Rincon Aug 29 '16 at 23:05
  • I use apache tomcat 7, yes I have the weld implementation jar in my classpath , I tested `@Named` and `@SessionScoped` from `javax.enterprise.context.SessionScoped` and still getting the same problem. – Sam Aug 29 '16 at 23:25
  • Man kink of hard to know or help you without more info or code.. – Esteban Rincon Aug 29 '16 at 23:32
  • I thought the code I gave above was enough, I don't know what other code I should add. for the moment I'll try converting my JSF managed beans to CDI ones to see if there will be a change .... I really really appreciate your help, and I hope you'll be there when I report any changes. – Sam Aug 29 '16 at 23:49
  • I'll try, good luck – Esteban Rincon Aug 30 '16 at 01:30
  • 2
    Cause of problem is not visible in information provided so far. Either the problem is actually in business service layer, or your project configuration is seriously messed up. – BalusC Aug 30 '16 at 07:58
  • Hello @BalusC, I've been waiting for your intervention, should I include my xml configuration files ? – Sam Aug 30 '16 at 12:42
  • Just create a [mcve] based on a scratchpad project with everything set to bare defaults and most recent versions as instructed in http://stackoverflow.com/tags/jsf/info – BalusC Aug 30 '16 at 12:54
  • @BalusC, I edited my question, please check it out ! – Sam Aug 31 '16 at 12:35

0 Answers0