0

我正在尝试使用 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 为 NULL 时,所有注册的参数根据 EclipseLink 日志正确注册:

    SELECT GUID, NAME, BSP_GUIG, CPP_GUID FROM CATALOGS WHERE ((CPP_GUID = ?) AND ((? IS NULL) OR (BSP_GUIG = ?)))
        bind => [18EC0EDB-21A4-4845-960A-D5D2BDAC7B87, null, null]

否则,当变量 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]

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

4

0 回答 0