Jpa 在EclipseLink中使用带有可选参数的命名查询时,参数绑定错误

Jpa 在EclipseLink中使用带有可选参数的命名查询时,参数绑定错误,jpa,oracle11g,eclipselink,jpql,Jpa,Oracle11g,Eclipselink,Jpql,我正在尝试使用JPA和EclipseLink进行数据库查找。我的数据库是Oracle 11.2.0。我定义了以下实体类: @Entity @Table(name = "BS_PROVIDERS") public class BsProvider { @Id @Column(name = "GUID") private String guid; public String getGuid() { return guid; } public void set

我正在尝试使用JPA和EclipseLink进行数据库查找。我的数据库是Oracle 11.2.0。我定义了以下实体类:

@Entity
@Table(name = "BS_PROVIDERS")
public class BsProvider {

    @Id
    @Column(name = "GUID")
    private String guid;
    public String getGuid() { return guid; }
    public void setGuid(String guid) { this.guid = guid; }

    @Column(name = "NAME")
    private String name;
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

}

@Entity
@Table(name = "CP_PROVIDERS")
public class CpProvider{

    @Id
    @Column(name = "GUID")
    private String guid;
    public String getGuid() { return guid; }
    public void setGuid(String guid) { this.guid = guid; }

    @Column(name = "NAME")
    private String name;
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

}

@NamedQueries({
    @NamedQuery(
        name = Catalog.FIND_BY_CPP_AND_BSP,
        query = "select c from Catalog c where (c.cpProvider = :cpProvider) and ( (:bsProvider IS NULL) or (c.bsProvider = :bsProvider))"
        )
})
@Entity
@Table(name = "CATALOGS")
public class Catalog {

    public static final String FIND_BY_CPP_AND_BSP = "Catalog.findByCppAndBsp";
    public static final String CP_PROVIDER_PARAM = "cpProvider";
    public static final String BS_PROVIDER_PARAM = "bsProvider";

    @Id
    @Column(name = "GUID")
    private String guid;
    public String getGuid() { return guid; }
    public void setGuid(String guid) { this.guid = guid; }

    @Column(name = "NAME")
    private String name;
    public String getName() { return name; }
    public void setName() { this.name = name; }

    @ManyToOne
    @JoinColumn(name = "CPP_GUID")
    private CpProvider cpProvider;
    public CpProvider getCpProvider() { return cpProvider; }
    public void setCpProvider(CpProvider cpProvider) { this.cpProvider = cpProvider; }

    @ManyToOne()
    @JoinColumn(name = "BSP_GUIG")
    private BsProvider bsProvider;
    public BsProvider getBsProvider() { return bsProvider; }
    public void setBsProvider(BsProvider bsProvider) { this.bsProvider = bsProvider; }

}
创建查询并设置参数的代码:

TypedQuery<Catalog> catalogQuery = em.createNamedQuery(Catalog.FIND_BY_CPP_AND_BSP, Catalog.class);
catalogQuery.setParameter(Catalog.CP_PROVIDER_PARAM, cpProvider);
catalogQuery.setParameter(Catalog.BS_PROVIDER_PARAM, bsProvider);
List<Catalog> catalogList = catalogQuery.getResultList();
否则,当变量bsProvider引用现有实体时,会出现以下异常:

Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Invalid column type
Error Code: 17004
Call: SELECT GUID, NAME, BSP_GUIG, CPP_GUID FROM CATALOGS WHERE ((CPP_GUID = ?) AND ((? IS NULL) OR (BSP_GUIG = ?)))
    bind => [18EC0EDB-21A4-4845-960A-D5D2BDAC7B87, com.bssys.ebpp.dbaccess.model.BsProvider@5dbbe8df, 44E8F4BF-CFDC-49DB-AB0B-718C72D6B4EF]

如您所见,第一个和第三个参数绑定正确(它们被主键值替换),但第二个参数没有。出现这种奇怪行为的原因是什么?

您尚未显示命名查询,但可能的原因是查询中没有用于确定参数使用何种类型的映射。这将强制eclipselink序列化对象,因为它无法确定您要对其执行的操作。命名查询在目录类定义中提供(请参阅@NamedQueries注释)。这很奇怪,因为第三个参数绑定正确:44E8F4BF-CFDC-49DB-AB0B-718C72D6B4EF。这并不奇怪-第三个参数是与c.bsProvider的比较,因此需要处理实体。第二个参数只是一个对象,因此提供程序不知道要对其执行什么操作,因此将其序列化。不管怎样,您是否最好执行空签入代码并执行不同的命名查询?您能否提供一个文档参考,说明EclipseLink在这种情况下如何处理命名参数?我可以接受答案,但我不能。JPA没有说明如何处理isNull,因此允许提供者传递他们想要的内容。由于您正在传递一个对象,因此从该对象中选取一个特定字段是不正确的,因为即使该对象不是空字段,该字段也可能为空。您的数据库不能处理序列化对象吗?
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Invalid column type
Error Code: 17004
Call: SELECT GUID, NAME, BSP_GUIG, CPP_GUID FROM CATALOGS WHERE ((CPP_GUID = ?) AND ((? IS NULL) OR (BSP_GUIG = ?)))
    bind => [18EC0EDB-21A4-4845-960A-D5D2BDAC7B87, com.bssys.ebpp.dbaccess.model.BsProvider@5dbbe8df, 44E8F4BF-CFDC-49DB-AB0B-718C72D6B4EF]