我正在尝试使用 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]
如您所见,第一个和第三个参数绑定正确(它们被主键值替换),但第二个不是。这种奇怪行为的原因是什么?