【问题标题】:hibernate unexpected end of subtree when dealing with collection of basics处理基础集合时休眠子树的意外结束
【发布时间】:2011-06-03 06:23:30
【问题描述】:

我有以下实体:

@Entity
public class AnalysisPolicy extends PersistentEntity{
    private Set nodeIds;

@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(
        name="analysis_policy_nodes",
        joinColumns=@JoinColumn(name="analysis_policy_id")
)
@Column(name="node_id")
public Set<Long> getNodeIds() {
    return nodeIds;
}

}

我正在尝试以下 JPQL 查询:

select p from AnalysisPolicy p where p.nodeIds is not empty

结果类似于:

10:11:16,665 DEBUG [org.hibernate.hql.ast.AST] --- SQL AST ---
 -[SELECT] QueryNode: 'SELECT'  querySpaces (AnalysisPolicy,analysis_policy_nodes)
    +-[SELECT_CLAUSE] SelectClause: '{select clause}'
    |  -[ALIAS_REF] IdentNode: 'analysispo0_.f_id as f1_8_' {alias=p, className=com.emc.dpa.datamodel.analysis.AnalysisPolicy, tableAlias=analysispo0_}
    +-[FROM] FromClause: 'from' FromClause{level=1, fromElementCounter=1, fromElements=1, fromElementByClassAlias=[p], fromElementByTableAlias=[analysispo0_], fromElementsByPath=[], collectionJoinFromElementsByPath=[], impliedElements=[]}
    |  -[FROM_FRAGMENT] FromElement: 'AnalysisPolicy analysispo0_' FromElement{explicit,collection join,not a fetch join,fetch non-lazy properties,classAlias=p,role=null,tableName=AnalysisPolicy,tableAlias=analysispo0_,origin=null,columns={,className=com.emc.dpa.datamodel.analysis.AnalysisPolicy}}
    -[WHERE] SqlNode: 'where'
       -[EXISTS] UnaryLogicOperatorNode: 'exists'
          -[SELECT] QueryNode: 'SELECT'  querySpaces (AnalysisPolicy,analysis_policy_nodes)
             +-[SELECT_CLAUSE] SelectClause: '{derived select clause}'
             +-[FROM] FromClause: 'from' FromClause{level=2, fromElementCounter=0, fromElements=1, fromElementByClassAlias=[], fromElementByTableAlias=[nodeids1_], fromElementsByPath=[], collectionJoinFromElementsByPath=[p.nodeIds], impliedElements=[]}
             |  -[FROM_FRAGMENT] ImpliedFromElement: 'analysis_policy_nodes nodeids1_' ImpliedFromElement{implied,collection join,not a fetch join,fetch non-lazy properties,classAlias=null,role=com.emc.dpa.datamodel.analysis.AnalysisPolicy.nodeIds,tableName={none},tableAlias=nodeids1_,origin=AnalysisPolicy analysispo0_,columns={,className=null}}
             -[WHERE] SqlNode: 'WHERE'
                -[THETA_JOINS] SqlNode: '{theta joins}'
                   -[SQL_TOKEN] SqlFragment: 'analysispo0_.f_id=nodeids1_.analysis_policy_id'

10:11:16,681 调试 [org.hibernate.hql.ast.ErrorCounter] throwQueryException():没有错误 10:11:16,712 错误 [org.hibernate.hql.PARSER]:0:0: 子树意外结束

后跟一个长堆栈跟踪。我发现了一个类似的stackoverflow问题here,问题在于基本实体集合的语法不同,所以我目前的想法是我的“不是空的”部分应该用其他东西替换。 另外,我无法让“不为空”工作。 "size(nodeIds)>1" 有效,但生成的 SQL 有一个内部选择,这在性能方面非常糟糕。

我有什么办法解决这个问题? (假设我不想将集合“升级”为实体集合)。

【问题讨论】:

    标签: hibernate jpa persistence jpql


    【解决方案1】:

    HQL 文档描述了以下语法,它也适用于 Hibernate 的 JPQL:

    select p from AnalysisPolicy p where exists elements(p.nodeIds)
    

    另请参阅:

    【讨论】:

    • 首先 - 谢谢,这确实是我想要的。问题是 - 这种语法是否适用于非基本集合(@OneToMany)?换句话说,这是“不是空的”的通用替代吗?
    • @radai:看起来elements 是为所有集合值属性定义的,包括对多关系。
    【解决方案2】:

    你可以试试这个:

    select p from AnalysisPolicy as p join p.nodeIds group by p
    

    【讨论】:

      猜你喜欢
      • 2011-01-05
      • 2015-01-08
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 2013-10-23
      • 2018-12-21
      • 2010-12-27
      • 1970-01-01
      相关资源
      最近更新 更多