JPA"对待"不起作用

时间:2016-08-02 09:04:31

标签: java jpa jpa-2.1

我的JPA 2.1查询有问题,但我不明白。我有以下实体:

@Entity
@Table
public class DocumentEntity {

    @Id
    private Integer id;

    @OneToMany(mappedBy = "document", cascade = CascadeType.ALL)
    private Set<AttributeEntity<?>> attributes;

    ...
}

AbstractEntity

@Entity
@Table
@Inheritance
@DiscriminatorColumn(name = "type")
public abstract class AttributeEntity<T> {

    @Id
    private Integer id;

    @Column
    @NotBlank
    private String name;

    @ManyToOne
    @JoinColumn(name = "document_id")
    private DocumentEntity document;

    ... getters and setters

    public abstract T getValue();
    public abstract void setValue(T value);
}

AbstractDateEntity

@Entity
@DiscriminatorValue("date")
public class AttributeDateEntity extends AttributeEntity<Date> {

    @Column(name = "date_value")
    @NotNull
    private Date value;

    @Override
    public Date getValue() {
        return value;
    }

    @Override
    public void setValue(Date value) {
        this.value = value;
    }
}

AbstractStringEntity

@Entity
@DiscriminatorValue("string")
public class AttributeStringEntity extends AttributeEntity<String> {

    @Column(name = "string_value")
    @NotNull
    private String value;

    @Override
    public String getValue() {
        return value;
    }

    @Override
    public void setValue(String value) {
        this.value = value;
    }
}

如您所见,文档可以有多个属性。这些属性有一个类型(字符串,日期,...)。在这里我的DAO课程:

public class DocumentDao {

    public List<DocumentEntity> find(Date from, Date to, String invoiceNumber) {

        StringBuilder queryString = new StringBuilder("SELECT d FROM DocumentEntity d ");
        if (from != null) {
            queryString.append("INNER JOIN TREAT(d.attributes as AttributeDateEntity) a1 WITH a1.name = 'from' AND a1.value >= :from ");
        }
        if (to != null) {
            queryString.append("INNER JOIN TREAT(d.attributes as AttributeDateEntity) a2 WITH a2.name = 'to' AND a2.value <= :to ");
        }
        if (invoiceNumber != null) {
            queryString.append("INNER JOIN TREAT(d.attributes as AttributeStringEntity) a3 WITH a3.name = 'invoiceNumber' AND a3.value = :invoiceNumber ");
        }

        Query query = getEntityManager().createQuery(queryString.toString());
        if (from != null) {
            query.setParameter("from", from);
        }
        if (to != null) {
            query.setParameter("to", to);
        }
        if (invoiceNumber != null) {
            query.setParameter("invoiceNumber", invoiceNumber);
        }
        return query.getResultList();
    }
}

但是当我从单元测试中使用这种方法时,例如:

@Test
public void testFind() throws Exception {
    dao.find(new Date(), null, "test");
}

我有以下例外:

Caused by: java.lang.IllegalArgumentException: Parameter value [Tue Aug 02 10:25:36 CEST 2016] did not match expected type [java.lang.String (n/a)]
    at org.hibernate.jpa.spi.BaseQueryImpl.validateBinding(BaseQueryImpl.java:874) [hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
    at org.hibernate.jpa.internal.QueryImpl.access$000(QueryImpl.java:80) [hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
    at org.hibernate.jpa.internal.QueryImpl$ParameterRegistrationImpl.bindValue(QueryImpl.java:248) [hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
    at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:620) [hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
    at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:180) [hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
    at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:49) [hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
    at com.actility.energy.customer.area.dao.DocumentDaoBean.buildQuery(DocumentDaoBean.java:197) [customer-area-ejb.jar:]
    at com.actility.energy.customer.area.dao.DocumentDaoBean.find(DocumentDaoBean.java:147) [customer-area-ejb.jar:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_65]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_65]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_65]
    at java.lang.reflect.Method.invoke(Method.java:497) [rt.jar:1.8.0_65]
    at org.jboss.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
    at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:437)
    at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:82) [wildfly-weld-9.0.2.Final.jar:9.0.2.Final]
    at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:93) [wildfly-weld-9.0.2.Final.jar:9.0.2.Final]
    at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
    at org.jboss.as.ejb3.component.invocationmetrics.ExecutionTimeInterceptor.processInvocation(ExecutionTimeInterceptor.java:43) [wildfly-ejb3-9.0.2.Final.jar:9.0.2.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
    at org.jboss.as.jpa.interceptor.SBInvocationInterceptor.processInvocation(SBInvocationInterceptor.java:47) [wildfly-jpa-9.0.2.Final.jar:9.0.2.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
    at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:437)
    at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64) [weld-core-impl-2.2.16.SP1.jar:2015-09-16 08:49]
    at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:83) [wildfly-weld-9.0.2.Final.jar:9.0.2.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
    at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45) [wildfly-ee-9.0.2.Final.jar:9.0.2.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
    at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:52)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
    at org.jboss.as.ejb3.component.interceptors.NonPooledEJBComponentInstanceAssociatingInterceptor.processInvocation(NonPooledEJBComponentInstanceAssociatingInterceptor.java:59) [wildfly-ejb3-9.0.2.Final.jar:9.0.2.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:254) [wildfly-ejb3-9.0.2.Final.jar:9.0.2.Final]
... 150 more

我不明白为什么要String而不是Date

0 个答案:

没有答案