Setter 未调用 selectOneMenu 中的例程

Setter Routine from selectOneMenu not called

我使用的是 Primefaces 6.1,其中一个 selectOneMenu 有问题。我已将页面缩小到仅 selectOneMenu-Item,但无法弄清楚问题出在哪里。

xhtml 页面:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui" template="/WEB-INF/template.xhtml">
    <ui:define name="content">
        <h:form id="formCenter">
            <div class="ContainerIndent">
                <div class="EmptyBox20"/>
                <p:selectOneMenu value="#{bankAccountEntryClearing.selectedInterfaceFile}"
                                 var="interfaceFileItem"
                                 converter="#{interfaceFileConverter}">  
                    <f:selectItem itemLabel="Bank-Daten auswählen" itemValue="#{null}" noSelectionOption="true"/>
                    <f:selectItems value="#{bankAccountEntryClearing.items}" 
                                   var="interfaceFileItem" 
                                   itemLabel="#{interfaceFileItem.fileName}" 
                                   itemValue="#{interfaceFileItem}"/>              
                    <p:column style="text-align: left">  
                        #{interfaceFileItem.fileName}
                    </p:column>  
                    <p:ajax event="change" process="@this" update=":formCenter:testSetterId"/>
                </p:selectOneMenu>
            </div>
            <p:inputText id="testSetterId" value="#{bankAccountEntryClearing.fileName}"/>
        </h:form>
    </ui:define>
</ui:composition>

转换器:

@ManagedBean
@SessionScoped
@Named("interfaceFileConverter")
public class InterfaceFileConverter implements Converter {

    private final Logger logger = Logger.getLogger(this.getClass().getName());

    @Inject
    private InterfaceFileFacade ejbFacade;

    private Integer getKey(String value) {
        Integer key = Integer.valueOf(value);
        return key;
    }

    public String getAsString(FacesContext fc, UIComponent uic, Object object) {
        if (object == null) return null;
        if (object instanceof InterfaceFile) 
            return String.valueOf(((InterfaceFile) object).getInterfaceFileId());
        return null;
    } 


    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.length() == 0) {
            logger.info("Interface Converter : null");
            return null;
        }
        InterfaceFile interfaceFile = this.ejbFacade.findInterfaceFile(getKey(value));
        logger.info("Interface Converter : " + interfaceFile.getInterfaceFileId());
        return interfaceFile;
    }
}

豆子:

@SessionScoped
@ManagedBean
@Named(value = "bankAccountEntryClearing")
public class BankAccountEntryClearing extends AbstractHouseController<InterfaceFile> implements Serializable {

    private static final long serialVersionUID = 1L;
    private final Logger logger = Logger.getLogger(this.getClass().getName());

    @Inject
    private InterfaceFileFacade         ejbFacade;

    private InterfaceFile               interfaceFile = null;
    private Integer                     houseId;
    private List<InterfaceFile>         interfaceFiles = null;

    public BankAccountEntryClearing() {
        super(InterfaceFile.class);
    }

    @PostConstruct
    public void init() {
        super.setFacade(ejbFacade);
    }

    public List<InterfaceFile> getItems() {
        if (this.getHouseId() == null)
            return null;

        if (this.getHouseId() != this.houseId) {
            interfaceFiles = ejbFacade.getInterfaceFiles(this.getHouseId(),1);
        }

        return interfaceFiles;
    }

    public InterfaceFile getSelectedInterfaceFile() {
        logger.info("Interface Bean getter");
        return interfaceFile;
    }

    public void setSelectedInterfaceFile(InterfaceFile interfaceFile) {
        logger.info("Interface Bean setter: " + interfaceFile.getFileName());
        this.interfaceFile      = interfaceFile;
    }

    public String getFileName() {
        if (this.interfaceFile != null)
            return this.interfaceFile.getFileName();
        return "";
    }
}

项目已加载探测器,可以选择。选择一个项目后,从转换器调用 getAsObject,但从不调用 setter-例程。

16:55:23,411 INFO  [com.np.propmgmt.controller.BankAccountEntryClearing] (default task-30) Interface Bean getter
16:55:23,412 INFO  [com.np.propmgmt.controller.BankAccountEntryClearing] (default task-30) Interface Bean getter
16:55:27,772 INFO  [com.np.propmgmt.converter.InterfaceFileConverter] (default task-48) Interface Converter : 69

我找到了一个 hind 并解决了这个问题。原因是 entity-class 对象 InterfaceFile 本身。 这个 JPA 实体 -class 是唯一一个由 Eclipse JPA-Tool 生成的实体。在这种情况下没有 "equals" 和 "hashCode" 功能 生成了主键。在选择项目时,"selectOneMenu" 将返回的 InterfaceFile(来自 getAsObject)与 列表(来自 getItems)和失败。添加“”后显示验证错误。

将这两个函数添加到 InterfaceFile-entity-class 后,一切正常。

验证错误:值无效