Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JSF selectOneMenu实体转换使用CDI转换器失败_Java_Jsf_Jsf 2_Primefaces_Cdi - Fatal编程技术网

Java JSF selectOneMenu实体转换使用CDI转换器失败

Java JSF selectOneMenu实体转换使用CDI转换器失败,java,jsf,jsf-2,primefaces,cdi,Java,Jsf,Jsf 2,Primefaces,Cdi,可能重复: 我有一个JSF页面,上面有两个p:selectOneMenu,它们都表示非常简单的实体 列表类型实体: @Entity @Table( name = "LISTTYPES" ) @NamedQueries ( { @NamedQuery( name = "...", query = "SELECT lty " + "FROM ListType lty " +

可能重复:

我有一个JSF页面,上面有两个
p:selectOneMenu
,它们都表示非常简单的实体

列表类型实体:

@Entity
@Table( name = "LISTTYPES" )
@NamedQueries
(
    {
        @NamedQuery( name  = "...",
                     query = "SELECT lty " +
                             "FROM ListType lty " +
                             "WHERE lty.name = :name "),
    }
)
public class ListType implements ClientDependent, Serializable
{
    @Id
    @Column( name = "LISTTYPE_ID" )
    private Long               id;

    @Basic( optional = false )
    @Column( name = "LIST_NO" )
    private Long               nbr;

    @Basic( optional = false )
    @Column( name = "LIST_NAME" )
    private String             name;

    @Column( name = "LIST_DESC" )
    private String             description;

    ...
}
监视原因实体:

@Entity
@Table( name = "MONITORINGREASONS" )
@NamedQueries
(
    {
        @NamedQuery( name  = "...",
                     query = "SELECT mtr " +
                             "FROM MonitoringReason mtr " +
                             "WHERE mtr.code = :code"),
    }
)
public class MonitoringReason implements Serializable
{
    @Id
    @Column( name = "MONITORINGREASON_ID" )
    private Long               id;

    @Basic( optional = false )
    @Column( name = "MONITORINGREASON_NO" )
    private String             code;

    @Basic( optional = false )
    @Column( name = "MONITORINGREASON_NAME" )
    private String             name;

    @Basic( optional = false )
    @Column( name = "MONITORINGREASON_DESC" )
    private String             description;

    ...
}
简单实体。注意,我省略了equals+hashCode方法,这两个实体都正确实现了这些方法

以下是一些示例数据:

列表类型数据:

LISTTYPE_ID  LIST_NO  LIST_NAME           LIST_DESC
      1         3       'WL'        'Watch List'
      0         4       'RL'        'Restricted List'
      2         5       'Emb'       'Embargo'
      7         7       'NRL'       'Not Recommended List'
   5009        14       'GWL'       'Global Watch List'
   5010        15       'GRL'       'Global Restricted List'
   5011        16       'PIL'       'Permanent Insider List'
监测原因数据:

MONITORINGREASON_ID  MONITORINGREASON_NO  MONITORINGREASON_NAME  MONITORINGREASON_DESC
        3                   'Ah'           'Ad-Hoc'              'Ad-Hoc'
        6                   'Al'           'Autom. Liste'        'Automatische Liste'
        4                   'Be'           'Beobachtung'         'Beobachtung'
        7                   'CLC'          'Limit Changes'       'Limit Changes'
        1                   'Fus'          'Fusion'              'Fusion'
        5                   'Li'           'Liste'               'Liste'
        2                   'Res'          'Research'            'Research Unternehmen'
上述实体的命名查询用于通过转换器查找实体:

ListTypeConverter.java:

@Named
@RequestScoped
public class ListTypeConverter implements Converter
{
    @Inject
    @SeamLogger
    private Logger log;

    @Inject
    private SessionHelper sessionHelper;

    @Inject
    private ListTypeService listTypeService;

    @Override
    public Object getAsObject( FacesContext ctx, UIComponent comp, String identifier )
    {
        this.log.info( getClass().getSimpleName() + ".getAsObject: " + identifier );

        if ( identifier == null )
        {
            return null;
        }

        ListType listType = this.listTypeService.findByClientIdAndName( this.sessionHelper.getLoginUser().getClientId(), identifier );

        this.log.info( "Returning " + listType.getName() +  "!" );

        return listType;
    }

    ...
}
@Named
@RequestScoped
public class MonitoringReasonConverter implements Converter
{
    @Inject
    @SeamLogger
    private Logger log;

    @Inject
    private SessionHelper sessionHelper;

    @Inject
    private MonitoringReasonService monitoringReasonService;

    @Override
    public Object getAsObject( FacesContext ctx, UIComponent comp, String identifier )
    {
        this.log.info( getClass().getSimpleName() + ".getAsObject: " + identifier );

        if ( identifier == null )
        {
            return null;
        }

        MonitoringReason monitoringReason = this.monitoringReasonService.findByClientIdAndCode( this.sessionHelper.getLoginUser().getClientId(), identifier );

        this.log.info( "Returning " + monitoringReason.getName() +  "!" );

        return monitoringReason;
    }

    ...
}
MonitoringReasonConverter.java:

@Named
@RequestScoped
public class ListTypeConverter implements Converter
{
    @Inject
    @SeamLogger
    private Logger log;

    @Inject
    private SessionHelper sessionHelper;

    @Inject
    private ListTypeService listTypeService;

    @Override
    public Object getAsObject( FacesContext ctx, UIComponent comp, String identifier )
    {
        this.log.info( getClass().getSimpleName() + ".getAsObject: " + identifier );

        if ( identifier == null )
        {
            return null;
        }

        ListType listType = this.listTypeService.findByClientIdAndName( this.sessionHelper.getLoginUser().getClientId(), identifier );

        this.log.info( "Returning " + listType.getName() +  "!" );

        return listType;
    }

    ...
}
@Named
@RequestScoped
public class MonitoringReasonConverter implements Converter
{
    @Inject
    @SeamLogger
    private Logger log;

    @Inject
    private SessionHelper sessionHelper;

    @Inject
    private MonitoringReasonService monitoringReasonService;

    @Override
    public Object getAsObject( FacesContext ctx, UIComponent comp, String identifier )
    {
        this.log.info( getClass().getSimpleName() + ".getAsObject: " + identifier );

        if ( identifier == null )
        {
            return null;
        }

        MonitoringReason monitoringReason = this.monitoringReasonService.findByClientIdAndCode( this.sessionHelper.getLoginUser().getClientId(), identifier );

        this.log.info( "Returning " + monitoringReason.getName() +  "!" );

        return monitoringReason;
    }

    ...
}
如您所见,两个简单的CDI转换器几乎是拷贝。唯一的区别是列表类型按名称查询,监控原因按代码查询。(请参阅命名查询,我检查了服务是否调用了正确的查询)

它们在JSF页面中使用,如:

<p:selectOneMenu id="list-type"
                 value="#{complianceCaseManager.selectedListType}"
                 converter="#{listTypeConverter}">
    <f:selectItems value="#{listTypeManager.selectableListTypes}"
                   var="ltp"
                   itemValue="#{ltp}"
                   itemLabel="#{ltp.description}" />
    <p:ajax process="@this" update="@form" />
</p:selectOneMenu>

<p:selectOneMenu id="monitoring-reason"
                 value="#{complianceCaseManager.selectedMonitoringReason}"
                 converter="#{monitoringReasonConverter}">
    <f:selectItems value="#{monitoringReasonManager.selectableMonitoringReasons}"
                   var="mtr"
                   itemValue="#{mtr}"
                   itemLabel="#{mtr.name}" />
    <p:ajax process="@this" update="@form" />
</p:selectOneMenu>
但是,当使用监控原因选择时,会记录以下内容:

2012-12-18 22:52:02,091 [http-thread-pool-8181(2)] INFO  de.company.project.MonitoringReasonConverter     - MonitoringReasonConverter.getAsObject: Fusion
2012-12-18 22:52:02,100 [http-thread-pool-8181(2)] ERROR de.company.project.MonitoringReasonService       - Monitoring reason not found for client ID = 1 with code Fusion
javax.persistence.NoResultException: getSingleResult() did not retrieve any entities.
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.throwNoResultException(EJBQueryImpl.java:1307)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getSingleResult(EJBQueryImpl.java:778)
    at de.company.project.MonitoringReasonService.findByClientIdAndCode(MonitoringReasonService.java:92)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
    at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:42)
    at sun.reflect.GeneratedMethodAccessor7832.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
    at sun.reflect.GeneratedMethodAccessor7831.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
    at $Proxy2626.findByClientIdAndCode(Unknown Source)
    at de.company.project.__EJB31_Generated__MonitoringReasonService__Intf____Bean__.findByClientIdAndCode(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:267)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52)
    at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137)
    at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:263)
    at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:110)
    at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105)
    at de.company.project.MonitoringReasonService$Proxy$_$$_Weld$Proxy$.findByClientIdAndCode(MonitoringReasonService$Proxy$_$$_Weld$Proxy$.java)
    at de.company.project.MonitoringReasonConverter.getAsObject(MonitoringReasonConverter.java:63)
    at de.company.project.MonitoringReasonConverter$Proxy$_$$_WeldClientProxy.getAsObject(MonitoringReasonConverter$Proxy$_$$_WeldClientProxy.java)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:171)
    at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectOneValue(MenuRenderer.java:201)
    at com.sun.faces.renderkit.html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:318)
    at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.getConvertedValue(SelectOneMenuRenderer.java:55)
    at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030)
    .
    .
    .
Qs

  • 为什么在转换过程中,name属性会同时用于
  • 是什么决定了name属性应该用于getAsObject方法字符串值,而不是像我一直假设的那样,将属性传递到
    itemLabel=“…”
    ?你是如何控制的
  • 在JSF规范中,这些信息隐藏在哪里?(如果不是在这里进行覆盖)

  • 我认为这将是转换器的问题。我发现了一个与此类似的问题,请检查此选项,它可能会有所帮助。

    最终的答案是,我的转换器的
    getAsString()
    方法定义了
    getAsObject
    接收的字符串。我一直认为该值是由JSF确定的,例如
    itemlab=“…”
    ,情况并非如此


    考虑到这一点,我觉得这样做是有道理的,但我很震惊,我在阅读和编程JSF的1.5年多时间里错过了这些信息…

    我要感谢你为我指出了解决方案。