Announcement Announcement Module
Collapse
No announcement yet.
facelets converter problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • facelets converter problem

    hi all,

    I have a problem developing a webflow and facelets application. I have writen a .xhtml page and the binding does not work.
    this is my page:
    HTML Code:
    <?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:ui="http://java.sun.com/jsf/facelets"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:f="http://java.sun.com/jsf/core">
        <ui:composition template="./../../facelets/template.xhtml">
            <ui:define name="body">
                <h:form>
                    <table align="center">
                        <tr>
                            <td> <h:outputText value="Name:"/></td>
                            <td> <h:inputText value="#{g1.name}"/><br/></td>
                        </tr>
                        <tr>
                            <td> <h:outputText value="Type:"/></td>
                            <td>
                                <h:selectOneMenu value="#{g1.goodType}" converter="GoodTypeCon">
                                    <f:selectItems value="#{gts}"/>
                                </h:selectOneMenu>
                            </td>
                        </tr>
                        <tr>
                            <td align="right"><h:commandButton  action="success" value="Add" class="botton"/></td>
                            <td><h:commandButton action="cancel" value="Cancel" class="botton"/></td>
                        </tr>
                    </table>
                </h:form>
            </ui:define>
        </ui:composition>
    </html>
    the webflow is this:
    HTML Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <flow xmlns="http://www.springframework.org/schema/webflow"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/webflow
    http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
    
    
    <var name="g1" class="beans.Good"/>
    
    	<view-state id="main" view="Main.xhtml">
            <transition on="out" to="out"/>
            <transition on="addGood" to="addGood"/>
    	</view-state>
    
        <view-state id="addGood" view="addGood.xhtml" model="g1">
            <on-entry>
                <evaluate expression="GoodTypeService.getItems()"  result="flowScope.gts"/>
            </on-entry>
            <transition on="success" to="main" bind="true">
                <evaluate expression="GoodService.insert(g1)"/>
            </transition>
            <transition on="cancel" to="main" bind="false"/>
        </view-state>
        
        <end-state id="out" view="exit.xhtml"/>
    </flow>
    my faces-config include the copnverter:
    Code:
    <faces-config version="1.2"
        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-facesconfig_1_2.xsd">
    
        <application>
            <view-handler>
                com.sun.facelets.FaceletViewHandler
            </view-handler>
        </application>  
    	
        converter-id>GoodTypeCon</converter-id>
            <converter-class>converters.GoodTypeCon</converter-class>
        </converter>
    </faces-config>
    and finally my converter code is:
    Code:
    package converters;
    
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.convert.Converter;
    import org.springframework.context.ApplicationContext;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.web.jsf.FacesContextUtils;
    import ro.depoman.beans.GoodType;
    import ro.depoman.impl.GoodTypeImpl;
    
    public class GoodTypeCon implements Converter {
    
        public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
            GoodType mu = new GoodType();
            try{
           
            GoodTypeImpl muImpl = new GoodTypeImpl();
            ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
            JpaTransactionManager emf = (JpaTransactionManager) ctx.getBean("transactionManager");
            muImpl.setEntityManagerFactory(emf.getEntityManagerFactory());
            mu = muImpl.getGoodTypeByName(arg2);
            }catch(Exception e){
               e.printStackTrace();
            }
            return mu;
        }
    
        public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
            GoodType gt;
            try{
            gt = (GoodType) arg2;
            return gt.getName();
            }catch(Exception e){
                e.printStackTrace();
            }
            return "";
        }
    
    }
    The GoodService.insert(g1); is not called at all, if i remove the <h:selectOneMenu value="#{g1.goodType}" converter="GoodTypeCon">
    <f:selectItems value="#{gts}"/>
    </h:selectOneMenu>
    the insertions goes as desired. I worked on this for several days and i can't figure it out. I am on a deadline.
    Please help.

  • #2
    First of all, is your converter getting called, and is it working as expected?

    Second, I'm not sure if you really need to specify a model with JSF. The SWF documentation is unclear as to how models work in this environment. I'm not sure if the bind attributes in the transition have any effect in this usage. Try hitting cancel. Does it still try to bind?

    Comment


    • #3
      thanks for the quick reply,

      The converter is called, and the result is as expected. It select from the database. I have tried to put a try {}catch to see if it throws any error but it
      does not.
      I have tried to hit cancel and it is still trying to bind, I can't get out of the state in any way.

      This is my dao implementation:

      Code:
      package ro.depoman.impl;
      
      import java.util.ArrayList;
      import java.util.List;
      import javax.faces.model.SelectItem;
      import javax.persistence.EntityManager;
      import javax.persistence.EntityTransaction;
      import javax.persistence.Query;
      import beans.GoodType;
      import GoodTypeDAO;
      
      
      public class GoodTypeImpl extends BaseDAOImpl<GoodType> implements GoodTypeDAO {
      
          public GoodType getGoodTypeByName(String name) {
             EntityManager manager = getEntityManagerFactory().createEntityManager();
              EntityTransaction tx = manager.getTransaction();
              GoodType entities = new GoodType();
              try {
                  tx.begin();
                  Query query = manager.createNativeQuery("select * from goodtypes gts where gts.name = '"+name+"';",GoodType.class);
                  entities = (GoodType) query.getSingleResult();
              } catch (Exception e) {
                  tx.rollback();
                  e.printStackTrace();
              }
              return entities;
          }
      
          @Override
          public List<GoodType> findAll(Class<GoodType> objectClass) {
              EntityManager manager = getEntityManagerFactory().createEntityManager();
              EntityTransaction tx = manager.getTransaction();
              List<GoodType> entities = new ArrayList<GoodType>();
              try {
                  tx.begin();
                  Query query = manager.createNativeQuery("select * from goodtypes;",GoodType.class);
                  entities = (List<GoodType>) query.getResultList();
              } catch (Exception e) {
                  tx.rollback();
                  e.printStackTrace();
              }
              return entities;
          }
      
           public List<SelectItem> getItems(){
              List<GoodType> ls = this.findAll(GoodType.class);
              List<SelectItem> lsi = new ArrayList<SelectItem>();
      
              for(int i=0;i<ls.size();i++){
                  lsi.add(new SelectItem(ls.get(i), ls.get(i).getName()));
              }
              return lsi;
          }
      }
      and this is my bean:

      Code:
      package ro.depoman.beans;
      
      import java.io.Serializable;
      import java.util.List;
      import javax.persistence.Column;
      import javax.persistence.Entity;
      import javax.persistence.GeneratedValue;
      import javax.persistence.GenerationType;
      import javax.persistence.Id;
      import javax.persistence.OneToOne;
      import javax.persistence.SequenceGenerator;
      import javax.persistence.Table;
      
      
      @Entity
      @Table(name = "GOODS")
      public class Good implements Serializable {
      
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO, generator = "myGen")
          @SequenceGenerator(name = "myGen", sequenceName = "goods_id_seq")
          @Column(name = "ID")
          private Long id;
          @Column(name = "NAME")
          
          @OneToOne
          private GoodType goodType;
      	
      	//getters and setters...
      }
      thanks again for the quick replay, and please help.

      Comment


      • #4
        Let's see what happens if we remove the explicit model handling.

        First of all, remove the model from your view-state, and remove the bind="true" and bind="false" from your transitions.

        On your page, add immediate="true" on your cancel button.

        Comment


        • #5
          hi,

          I have removed the explicit model handling and the binding attributes, and added the immediate="true" on the cancel button.
          The cancel button now works fine, and i can get out of the state with it, but the binding does not work. I have tested the 'g1' var in the view state adding this:
          Code:
          <on-render> 
                  <evaluate expression="GoodService.info(g1)"/>
             </on-render>
          In this method i simply print the attributes of the g1 var.
          When I add
          HTML Code:
           <h:selectOneMenu value="#{g1.goodType}"                 converter="GoodTypeCon">
                          <f:selectItems value="#{gts}"/>
                     </h:selectOneMenu>
          to the page the 'goodType' from the bean is null, and also the name is null. This clearly means that there is no binding. If i remove the h:selectOneMenu and leave only the primitive type 'name' the binding works just fine.

          Comment


          • #6
            You've got a setter in g1, right? Set a breakpoint there and see what's being set there on submit.

            I'm assuming that the select is showing up fine and with the right values on the page.

            Comment


            • #7
              The setter is not even called.
              this is my select that is showed by hibernate:
              Code:
              INFO: Container org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/DepoMan] has already been started
              name: name passwd:pa
              Hibernate: select * from employs as empl where empl.name = 'name' and empl.passwd = 'pa';
              Hibernate: select * from goodtypes;
              Hibernate: select good0_.ID as ID2_1_, good0_.goodType_ID as goodType3_2_1_, good0_.NAME as NAME2_1_, goodtype1_.ID as ID3_0_, goodtype1_.DESCRIPTION as DESCRIPT2_3_0_, goodtype1_.NAME as NAME3_0_ from GOODS good0_ left outer join GOODTYPES goodtype1_ on good0_.goodType_ID=goodtype1_.ID where good0_.goodType_ID=?
              Hibernate: select good0_.ID as ID2_1_, good0_.goodType_ID as goodType3_2_1_, good0_.NAME as NAME2_1_, goodtype1_.ID as ID3_0_, goodtype1_.DESCRIPTION as DESCRIPT2_3_0_, goodtype1_.NAME as NAME3_0_ from GOODS good0_ left outer join GOODTYPES goodtype1_ on good0_.goodType_ID=goodtype1_.ID where good0_.goodType_ID=?
              Hibernate: select good0_.ID as ID2_1_, good0_.goodType_ID as goodType3_2_1_, good0_.NAME as NAME2_1_, goodtype1_.ID as ID3_0_, goodtype1_.DESCRIPTION as DESCRIPT2_3_0_, goodtype1_.NAME as NAME3_0_ from GOODS good0_ left outer join GOODTYPES goodtype1_ on good0_.goodType_ID=goodtype1_.ID where good0_.goodType_ID=?
              Getter: null
              Getter: null
              Getter: null
              Hibernate: select * from goodtypes gts where gts.name = 'vopsea';
              Hibernate: select good0_.ID as ID2_1_, good0_.goodType_ID as goodType3_2_1_, good0_.NAME as NAME2_1_, goodtype1_.ID as ID3_0_, goodtype1_.DESCRIPTION as DESCRIPT2_3_0_, goodtype1_.NAME as NAME3_0_ from GOODS good0_ left outer join GOODTYPES goodtype1_ on good0_.goodType_ID=goodtype1_.ID where good0_.goodType_ID=?
              ps: i can't figure out the hibernate select, my intention is to have a bean of type 'good' that has a property of type 'goodType'. In the GoodType bean i have mapped this:
              Code:
              @OneToOne(mappedBy = "goodType")
                  private Good good;
              and in the 'good' bean i have:
              Code:
               @OneToOne
                  private GoodType goodType;
              As fare as i know this is ok

              and my full bean is this:

              Code:
              import javax.persistence.GenerationType;
              import javax.persistence.Id;
              import javax.persistence.OneToOne;
              import javax.persistence.SequenceGenerator;
              import javax.persistence.Table;
              
              @Entity
              @Table(name = "GOODS")
              public class Good implements Serializable {
              
                  @Id
                  @GeneratedValue(strategy = GenerationType.AUTO, generator = "myGen")
                  @SequenceGenerator(name = "myGen", sequenceName = "goods_id_seq")
                  @Column(name = "ID")
                  private Long id;
                  @Column(name = "NAME")
                  private String name;
                  @OneToOne
                  private GoodType goodType;
                  
                  public Long getId() {
                      return id;
                  }
              
                  public void setId(Long id) {
                      this.id = id;
                  }
                  
                  public String getName() {
                      return name;
                  }
                  
                  public void setName(String name) {
                      this.name = name;
                  }
              	
                  public GoodType getGoodType() {
                      System.out.println("Getter: "+goodType);
                      return goodType;
                  }
              
                  public void setGoodType(GoodType goodType) {
                      System.out.println("Setter: "+goodType);
                      this.goodType = goodType;
                  }
              }
              I suppose that the setter is not called because the submit state is not passed and it does not get to the point to bind the values to the g1 var and then persist it. So I am stuck at the submit and the convert step. I can't figure this out what is the problem . I have set the
              Code:
              <context-param>
                      <param-name>facelets.DEVELOPMENT</param-name>
                      <param-value>true</param-value>
                  </context-param>
              but nothing is thrown in the page...

              thanks for the quick replay.

              Comment

              Working...
              X