0 Replies Latest reply on Sep 10, 2008 11:26 PM by Tobias Kilian

    Converter only in one direction?

    Tobias Kilian Newbie

      Hi!


      short version: Is it somehow possible to have a Converter accepting an MyEntity Instance as input and get only instance.getId (String) out of it to store in the model?


      long version:
      I'm trying to write my own converter. I have a the two classes User and Employee:


      USER is managed by Hibernate and therefore an Entity :


      @Entity(optimisticLock = OptimisticLockType.DIRTY, dynamicUpdate = true)
      @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
      @javax.persistence.Entity
      @Table(name = "MB_USER", uniqueConstraints = @UniqueConstraint(columnNames = "KENNUNG"))
      public class Benutzer
                implements
                     java.io.Serializable,
                     HibernateManagedEntity {
      
           private static final long serialVersionUID = 1L;
      
           protected BigDecimal id;
           protected String kennung;
           protected String kennwort;
           protected String employeeid;
      ...



      EMPLOYEE is just a dummy class which gets filled with proper values from 'external' (actually it's the same db, but it could be any other system):


      public class Employee extends ExternalEntity implements java.io.Serializable {
           protected String id;
           protected String label;
      
           // Getters and Setters
           ...
      



      The property User.employeeid is semantically a foreign key but without the db constraint for technical reasons.
      When editing a User, I want to select the Employees like this:


      <h:selectOneMenu id="xy" value="userManager.instance.employeeid">
          <s:selectItems id="select" value="employeeManager.resultList" var="emp" label="#{emp.label}"/>
          <mb:convertEntity managerName="employeeManager"/>
      </h:selectOneMenu>



      where the mb:convertEntity is my own implementation similiar to s:convertEntity:


      Name("com.mobilanten.mowita.werkbank.converter.EntityConverter")
      @Scope(CONVERSATION)
      @Converter
      @BypassInterceptors
      public class EntityConverter
                implements
                     javax.faces.convert.Converter,
                     Serializable {
           private static final long serialVersionUID = 1L;
      
           private String managerName;
           private EntityStore store;
      
           @Create
           public void create() {
                store = EntityStore.instance();
           }
      
           private void init() {
                if (getManager() != null) {
                     store.setManager(getManager());
                } else
                     throw new IllegalStateException(
                               "manager not defined. you must define the attribute 'managerName' for tag mb:entityConverter!");
           }
      
           @SuppressWarnings("unchecked")
           @Transactional
           public String getAsString(FacesContext facesContext, UIComponent cmp,
                     Object value) throws ConverterException {
                init();
                if (value == null) {
                     return null;
                }
                if (value instanceof String) {
                     return value.toString();
                } else          
                if (value instanceof Entity) {
                     return ((Entity) value).getId().toString();
                } else
                     throw new ClassCastException(
                               "Value to convert is not a derivative of com.mobilanten.mowita.werkbank.Entity but "
                                         + value.getClass().getName());
           }
      
           @Transactional
           public Object getAsObject(FacesContext facesContext, UIComponent cmp,
                     String value) throws ConverterException {
                init();
                if (value == null) {
                     return null;
                }
                return value; // instead of store.get(value), which would give me the real entity; i want the id only
           }
      
           @SuppressWarnings("unchecked")
           public Manager<Entity> getManager() {
                return (Manager<Entity>) Component.getInstance(getManagerName());
           }
      
           public String getManagerName() {
                return managerName;
           }
      
           public void setManagerName(String aManagerName) {
                managerName = aManagerName;
           }
      




      This gives me the expected html output with employee.id as value and label as label:


      ..
       <option value="287">Kilian,Tobias</option>
      ...
      



      Now there is no Employee member in User, only the String.
      So I changed getAsObject(..) to only return the id. This gives me a facelets error with the content of
      javax.faces.component.UISelectOne.INVALID


      As a workaround i thought about extending User with something like


      public setEmployeeByInstance( Employee employee) {
          setEmployee( employee.getId());
      }
      


      but I hope this can be avoided....


      Thanks in advance for any help!