EclipseLink JPA CriteriaQuery正在创建错误的SQL查询

时间:2015-11-10 01:28:14

标签: java jpa eclipselink criteria-api

我正在尝试使用LazyDataModel在Primefaces数据表中为任何实体实现通用过滤系统,但在尝试搜索一对多关系中涉及的字段时会给我带来问题,因为它会生成错误的SQL查询,我的代码如下:将跳过一些不相关的部分,使其保持简单:

实体是客户端和故障:

@Entity
@Table(name = "ges_fault")
public class Fault extends Item implements Serializable, ItemIf{

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "client_id", nullable = true)
private Client client;

// Getters and setters

客户端类:

@Entity
@Table(name="ges_client")
public class Client extends Item implements Serializable, ItemIf {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;


@OneToMany(cascade = CascadeType.ALL,mappedBy="client", fetch = FetchType.LAZY)
private List<Fault> faults;

// Getters and setters

要抽象问题,最终条件查询如下所示:

CriteriaBuilder qb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Fault> c = qb.createQuery(Fault.class);
Root<Fault> root = c.from(Fault.class);
c.select(root);
List<Predicate> predicates = new ArrayList<Predicate>();
Expression<String> exp = root.get("client");
predicates.add(qb.like(exp,"%" + 1 + "%"));
c.where(predicates.toArray(new Predicate[]{}));
List<Fault>result = q.getResultList();

return result;

我得到的错误是:

  

内部例外:   com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:你有一个   SQL语法错误;查看与您的手册相对应的手册   MySQL服务器版本,用于在“LIKE”%1%'AND附近使用正确的语法   (t0.ID = t1.client_id))第1行的LIMIT 0,12'

错误代码:1064致电:

  

SELECT t1.ID AS a1,t1.NOMBRE AS a8,t1.client_id AS a9 FROM   ges_client t0,ges_fault t1 WHERE(LIKE?AND(t0.ID =   t1.client_id))LIMIT?,? bind =&gt; [3个参数绑定]查询:   ReadAllQuery(referenceClass = Falta sql =“SELECT t1.ID AS a1,t1.NOMBRE   AS a8,t1.client_id AS a9 FROM ges_client t0,ges_falta t1 WHERE(   喜欢 ? AND(t0.ID = t1.client_id))LIMIT?,?“)at   org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)     在   org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:682)     在   org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)     在   org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002)     在   org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)     在   org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)

因为我正在尝试做的事情,所以我无法使用这种查询:

Expression<String> exp = root.get(Fault_.client);

所以这不是一个可能的解决方案。

我希望有人可以帮助我。

1 个答案:

答案 0 :(得分:1)

您可能希望过滤客户的name媒体资源。在这种情况下,请使用以下语法之一,具体取决于您是否使用了类型安全的MetaModel:

Path<Client> client = root.get(Fault_.client);
Path<String> exp = client.get(Client_.name);  

或:

Path<Client> client = root.get("client");
Path<String> exp = client.get("name");  

在这两种情况下,您都可以避免在Path中指定类,或者甚至可以避免显式实例化客户端变量:

Path exp = root.get(Fault_.client).get(Client_.name);

Path client = root.get(Fault_.client);
Path exp = client.get(Client_.name);  

使用属性名称"client""name"代替元模型,都是合法的,等效的。

之后,按照您已经完成的创建Predicate表达式的步骤进行操作。