java.lang.IllegalArgumentException:来自托管类型[T]的属性[A]不存在

时间:2013-03-22 12:38:24

标签: java jpa criteria

我正在尝试使用JPA 2.0 Criteria API执行从我的数据库中检索某些数据的搜索页面。每当我尝试进行搜索时,我都会收到相同的异常错误。

这是我的搜索方法:

public List<Matches> search(SearchCommercialsDTO searchCommercialsDTO) {

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Matches> criteria = builder.createQuery( Matches.class );
    Root<Matches> matchesRoot = criteria.from( Matches.class );
    criteria.select( matchesRoot );

    List<Predicate> predicateList = new ArrayList<Predicate>();

    Predicate date, equipmentName, channelCode, advertiserName, agencyName, productName, duration;

    if(!ObjectUtil.isEmpty(searchCommercialsDTO.getEquipmentName())) {
        equipmentName = builder.like(matchesRoot.get("ID_RECORDER_FILES.EQUIPMENT_NAME").as(String.class), searchCommercialsDTO.getEquipmentName());
        predicateList.add(equipmentName);
    }
    if(!ObjectUtil.isEmpty(searchCommercialsDTO.getChannelCode())) {
        channelCode = builder.equal(matchesRoot.get("ID_RECORDER_FILES.CHANNEL_CODE"), searchCommercialsDTO.getChannelCode());
        predicateList.add(channelCode);
    }
    if(!ObjectUtil.isEmpty(searchCommercialsDTO.getAdvertiserName())) {
        advertiserName = builder.equal(matchesRoot.get("ID_SOURCE_MATERIAL.ADVERTISER_NAME"), searchCommercialsDTO.getAdvertiserName());
        predicateList.add(advertiserName);
    }
    if(!ObjectUtil.isEmpty(searchCommercialsDTO.getAgencyName())) {
        agencyName = builder.equal(matchesRoot.get("ID_SOURCE_MATERIAL.AGENCY_NAME"), searchCommercialsDTO.getAgencyName());
        predicateList.add(agencyName);
    }
    if(!ObjectUtil.isEmpty(searchCommercialsDTO.getProductName())) {
        productName = builder.equal(matchesRoot.get("ID_SOURCE_MATERIAL.PRODUCT_NAME"), searchCommercialsDTO.getProductName());
        predicateList.add(productName);
    }

    Predicate[] predicates = new Predicate[predicateList.size()];
    predicateList.toArray(predicates);
    criteria.where(predicates);

    return em.createQuery(criteria).getResultList();
}

当它试图执行这部分时:

equipmentName = builder.like(matchesRoot.get("ID_RECORDER_FILES.EQUIPMENT_NAME").as(String.class), searchCommercialsDTO.getEquipmentName());

抛出以下异常:

java.lang.IllegalArgumentException: The attribute [ID_RECORDER_FILES.EQUIPMENT_NAME] from the managed type [EntityTypeImpl@112477145:Matches [ javaType: class net.checkmidia.auditoria.entity.Matches descriptor: RelationalDescriptor(net.checkmidia.auditoria.entity.Matches --> [DatabaseTable(MATCHES)]), mappings: 12]] is not present.
    at org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl.getAttribute(ManagedTypeImpl.java:147)
    at org.eclipse.persistence.internal.jpa.querydef.FromImpl.get(FromImpl.java:312)
    at net.checkmidia.auditoria.business.MatchesBO.search(MatchesBO.java:50)
    at net.checkmidia.auditoria.session.MatchesSession.searchMatches(MatchesSession.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    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.GeneratedMethodAccessor126.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    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.GeneratedMethodAccessor72.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    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)
    ... 51 more

这是如何引起的?如何解决?

2 个答案:

答案 0 :(得分:2)

更改

matchesRoot.get("ID_RECORDER_FILES.EQUIPMENT_NAME")

matchesRoot.get("ID_RECORDER_FILES").get("EQUIPMENT_NAME")

并验证“ID_RECORDER_FILES”是Java类Matches字段的名称,“EQUIPMENT_NAME”是“ID_RECORDER_FILES”字段类中字段的名称。

方法get()采用属性的名称,因此您必须只传递id,然后使用生成的Path来获取该对象中包含的字段。

答案 1 :(得分:1)

matchesRoot.get(&#34; ID_RECORDER_FILES&#34;)。get(&#34; EQUIPMENT_NAME&#34;)为我做了诀窍。