简体   繁体   English

使用 CriteriaBuilder 的 JPA 左外连接导致错误:部分对象查询不允许维护缓存或被编辑

[英]JPA left outer join using CriteriaBuilder results in error: Partial object queries are not allowed to maintain the cache or be edited

I have the following entity relationships我有以下实体关系

Product产品

@Entity
@Table(name="PRODUCTS")
public class Product

@Id
@Column(name="product_id")
private long productId;

@ManyToOne
@JoinColumn(name="EMP_NUMBER")
private Employee employee3; 
....
....

Employee员工

@Entity
@Table(name="EMPLOYEES")
public class Employee

@Id
@Column(name="EMP_NUMBER")
private String empNumber;

@Column(name="EMP_NAME")
private String employeeName;

@OneToMany(mappedBy="employee3")
private List<Product> Product3;

....
....

In DAOImpl class I have the following在 DAOImpl 类中,我有以下内容

CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Product> cq = 
            cb.createQuery(Product.class);
Root<Product> c = cq.from(Product.class);
Join<Product, Employee> join = 
           c.join(Product_.employee3, JoinType.LEFT);
cq.multiselect(c.get(Product_.productId),        
           c.get(Product_.employee3));

However when I execute, I am getting the following errors但是,当我执行时,出现以下错误

org.eclipse.persistence.exceptions.QueryException Exception Description: Partial object queries are not allowed to maintain the cache or be edited. org.eclipse.persistence.exceptions.QueryException 异常说明:部分对象查询不允许维护缓存或被编辑。
You must use dontMaintainCache().您必须使用 dontMaintainCache()。 Query: ReadAllQuery(referenceClass=Product ) at org.eclipse.persistence.exceptions.QueryException.cannotCachePartialObjects (QueryException.java:388) at org.eclipse.persistence.queries.ObjectLevelReadQuery.prepareQuery (ObjectLevelReadQuery.java:2160)查询:在 org.eclipse.persistence.exceptions.QueryException.cannotCachePartialObjects (QueryException.java:388) 在 org.eclipse.persistence.queries.ObjectLevelReadQuery.prepareQuery (ObjectLevelReadQuery.java:2160) 的 ReadAllQuery(referenceClass=Product)

What I am trying to achieve is to generate the following SQL我想要实现的是生成以下 SQL

SELECT p.product_id,
          emp.emp_name
     FROM products p
          LEFT OUTER JOIN employees emp
             ON (p.emp_number = emp.emp_number)

How can I do this and get rid of errors?我怎样才能做到这一点并摆脱错误?

I have resolved the issue by adding the below mentioned line, might be useful to others if they encounter same problem what been mentioned in question.我已经通过添加下面提到的行解决了这个问题,如果他们遇到同样的问题,可能对其他人有用。

((org.eclipse.persistence.jpa.JpaQuery)query).getDatabaseQuery().dontMaintainCache();

Another better option is provided here这里提供另一个更好的选择

Thanks谢谢

According to this , there are two ways to create a criteria query createQuery(class) and createQuery() without the parameter.根据,有两种方法可以创建条件查询createQuery(class)createQuery()不带参数。 The first method creates a CriteriaQuery cast the result to class .第一个方法创建一个 CriteriaQuery 将结果转换为class

This means to resolve the problem, you can change CriteriaQuery<Product> cq = cb.createQuery(Product.class);这意味着要解决问题,您可以更改CriteriaQuery<Product> cq = cb.createQuery(Product.class); to this one CriteriaQuery<Product> cq = cb.createQuery();到这一点CriteriaQuery<Product> cq = cb.createQuery(); . .

And then use an Iterator to retrieve the result.然后使用Iterator来检索结果。

Iterator products = query.getResultList().iterator();

In my case and according to this: https://bugs.eclipse.org/bugs/show_bug.cgi?id=303205 The issue happens when you apply a multiselect and don't have a constructor with the selected parameters in the representation object.在我的情况下,根据这个: https ://bugs.eclipse.org/bugs/show_bug.cgi?id=303205 当您应用多选并且在表示对象中没有具有选定参数的构造函数时会发生此问题.

For instance if you have例如,如果你有

Select empNumber,employeeName from Employee

Then in your entity or representation object you need a constructor:然后在您的实体或表示对象中,您需要一个构造函数:

public Employee(int empNumber, StringemployeeName ){...}

Be careful since the order of the parameters matter.因为参数的顺序很重要,所以要小心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM