关联实体和非关联实体之间的连接,导致在 JPQL 中使用 Lazy fetch 生成非持久实体不断抛出 JpqlSyntaxException

Posted

技术标签:

【中文标题】关联实体和非关联实体之间的连接,导致在 JPQL 中使用 Lazy fetch 生成非持久实体不断抛出 JpqlSyntaxException【英文标题】:Join between associated and non associated entities, result into non persistent entity in JPQL with Lazy fetch keeps throwing JpqlSyntaxException 【发布时间】:2021-04-04 16:31:25 【问题描述】:

这个查询不断给我不同的错误 我怀疑我对构建 JPQL 查询的理解。

请帮我找出问题所在。

我正在尝试在直接关联实体和间接关联实体之间加入,并在非持久 DTO 中获得结果。

public List leaveRequestsReport(List employeesGroupIds) 
    if(employeesGroupIds!=null && employeesGroupIds.size()==0) 
        employeesGroupIds =null; 
    return persistence.getEntityManager().
        createQuery("select new com.company.vp.workflow.LeaveRequestRow(at.requestState.request.requestNumber, " 
        + "e.employeeNumber, e.fullName, at.requestState.request.submissionDate, e.employeesGroup.name, at.requestState.request.states) " + " from vp$RequestStateAttribute at "
        + " INNER JOIN at.requestState INNER JOIN at.requestState.request , "
        + " vp$Employee e INNER JOIN e.employeesGroup "
        + " where at.requestState.request.subjectType = 10 " 
        + " and at.requestState.request.requestKind = 20 " )
        .getResultList();

我得到的例外

com.haulmont.cuba.core.sys.jpql.JpqlSyntaxException: Errors found for input JPQL:[select new com.company.vp.workflow.LeaveRequestRow(at.requestState.request.requestNumber, e.employeeNumber, e.fullName, at.requestState.request.submissionDate, e.employeesGroup.name, at.requestState.request.states)  from vp$RequestStateAttribute at  INNER JOIN at.requestState INNER JOIN at.requestState.request ,  vp$Employee e INNER JOIN e.employeesGroup  where at.requestState.request.subjectType = 10  and at.requestState.request.requestKind = 20]
No variable name found [Join variable: null]
No variable name found [Join variable: null]
No variable name found [Join variable: null]    
at com.haulmont.cuba.core.global.QueryParserAstBased.getTree(QueryParserAstBased.java:76) ~[cuba-global-7.2.6.jar:7.2.6]    
at com.haulmont.cuba.core.global.QueryParserAstBased.getAnalyzer(QueryParserAstBased.java:84) ~[cuba-global-7.2.6.jar:7.2.6]    
at com.haulmont.cuba.core.global.QueryParserAstBased.getEntityName(QueryParserAstBased.java:101) ~[cuba-global-7.2.6.jar:7.2.6]    
at com.haulmont.cuba.core.sys.QueryImpl.transformQueryString(QueryImpl.java:247) ~[cuba-core-7.2.6.jar:7.2.6]    
at com.haulmont.cuba.core.sys.QueryImpl.getQuery(QueryImpl.java:134) ~[cuba-core-7.2.6.jar:7.2.6]    
at com.haulmont.cuba.core.sys.QueryImpl.getResultList(QueryImpl.java:409) ~[cuba-core-7.2.6.jar:7.2.6]

实体如下 // 映射是 100% 正常工作

@Table(name = "VP_REQUEST_STATE")
@Entity(name = "vp$RequestState")
public class RequestState extends BaseUuidEntity implements AttributeHolder 
private static final long serialVersionUID = 6052950589685024134L; @OnDeleteInverse(DeletePolicy.CASCADE)

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REQUEST_ID")
protected Request request;  

@Composition
@OneToMany(mappedBy = "requestState")
protected List requestStateAttributes; 
// setters and getters go here 

@Table(name = "VP_REQUEST_STATE_ATTRIBUTE")
@Entity(name = "vp$RequestStateAttribute")
public class RequestStateAttribute extends BaseUuidEntity implements Creatable, ValuedAttributable 
private static final long serialVersionUID = 7406123321282514785L;

@OnDeleteInverse(DeletePolicy.CASCADE)
@NotNull
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "REQUEST_STATE_ID")
protected RequestState requestState;

//other non related attribute and getter and setters go here 

@Table(name = "VP_REQUEST")
@Entity(name = "vp$Request")
public class Request extends BaseUuidEntity 
private static final long serialVersionUID = 7073994286444570051L;
@Column(name = "REQUEST_NUMBER")
protected String requestNumber;
@Column(name = "REQUEST_KIND")
protected Integer requestKind;

@Column(name = "SUBJECT_TYPE")
protected Integer subjectType;

@Column(name = "SUBJECT_ID")
protected UUID subjectId;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "SUBMISSION_DATE")
protected Date submissionDate;

@Composition
@OneToMany(mappedBy = "request")
protected List states;

//other non related attributes and setters and getters go here.

【问题讨论】:

【参考方案1】:

这是我进行的另一次试验,我得到了一个不同的例外

public List leaveRequestsReport(List employeesGroupIds) 
if(employeesGroupIds!=null && employeesGroupIds.size()==0) 
employeesGroupIds =null; 
return persistence.getEntityManager().
   createQuery("select new com.company.vp.workflow.LeaveRequestRow(rq.requestNumber, " 
 + "e.employeeNumber, e.fullName, rq.submissionDate, eg.name, rq.states) " 
 + " from vp$RequestStateAttribute at " 
 + " INNER JOIN at.requestState st INNER JOIN at.requestState.request rq, "
 + " vp$Employee e INNER JOIN e.employeesGroup eg"
 + " where rq.subjectType = 10 " 
 + " and rq.requestKind = 20 " ) 
.getResultList();


我得到的例外是

java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:Exception Description: 
Problem compiling [select new com.company.vp.workflow.LeaveRequestRow(rq.requestNumber, e.employeeNumber, e.fullName, rq.submissionDate, eg.name, rq.states)  from vp$RequestStateAttribute at INNER JOIN at.requestState st INNER JOIN at.requestState.request rq,  vp$Employee e INNER JOIN e.employeesGroup eg where rq.subjectType = 10  and rq.requestKind = 20 ].[127, 136] The state field path 'rq.states' cannot be resolved to a collection type.    
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1750) ~[org.eclipse.persistence.jpa-2.7.3-7-cuba.jar:na]    
at com.haulmont.cuba.core.sys.QueryImpl.buildJPAQuery(QueryImpl.java:229) ~[cuba-core-7.2.6.jar:7.2.6]    
at com.haulmont.cuba.core.sys.QueryImpl.getQuery(QueryImpl.java:138) ~[cuba-core-7.2.6.jar:7.2.6]    
at com.haulmont.cuba.core.sys.QueryImpl.getResultList(QueryImpl.java:409) ~[cuba-core-7.2.6.jar:7.2.6]

【讨论】:

以上是关于关联实体和非关联实体之间的连接,导致在 JPQL 中使用 Lazy fetch 生成非持久实体不断抛出 JpqlSyntaxException的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 实体之间的自定义关联

关联实体和实体之间有什么区别?

JPQL 查询在测试中工作,而不是在生产中

关联实体和关联关系属性之间的区别?

实体与实体之间的联系

在实体框架 EDMX 中创建视图之间的关联时出错