“org.hibernate.QueryException:重复关联路径”错误(可能需要包含两次表)

问题描述 投票:0回答:1

我正在使用Hibernate来实现一个Search页面,其中可能会或可能不会使用不同的标准。一个标准是ID中的SpecialTable。另一个标准是"Or"MainTable中的SpecialTable。一切都是可选的。

假设我同时提供标准#1和#2。在这种情况下,我想分别加入SpecialTable两次,使用不同的别名,因为这些标准并不相互依赖。

// Optional Criterion #1
if (searchCriteria.getSpecialId() != null) {
    criteriaQuery.createAlias("specialTable", "specialTableJoin1", JoinType.INNER_JOIN);
    criteriaQuery.add(Restrictions.eq("specialTableJoin1.id", searchCriteria.getSpecialId()));
}   

// ...

// Optional Criterion #2
if (!StringUtils.isBlank(searchCriteria.getRequestPublicationTitle())) {

    criteriaQuery.createAlias("specialTable", "specialTableJoin2", JoinType.LEFT_OUTER_JOIN);

    String titleForQuery = "%" + searchCriteria.getRequestPublicationTitle().replaceAll("^.*,", "").trim() + "%";
    Disjunction requestOrPublicationTitle = Restrictions.disjunction();
    requestOrPublicationTitle.add(Restrictions.ilike("title", titleForQuery));
    requestOrPublicationTitle.add(Restrictions.ilike("specialTableJoin2.publicationTitle", titleForQuery));

错误:

org.hibernate.QueryException: duplicate association path: specialTable

有解决方案吗我的别名是不同的,但它仍然不起作用。

hibernate hibernate-criteria
1个回答
0
投票

这是一个古老的Hibernate bug - https://hibernate.atlassian.net/browse/HHH-879 - 自2005年以来仍然开放!

唯一的解决方案是预先定义所有别名,而不是每个使用的标准。但如果在别名创建中使用不同的JoinType(INNER与LEFT_OUTER_JOIN),则可能会出现问题。如果它是全部相同的JoinType,那么你已经设置好了。

我使用的解决方法是定义一个公共LEFT_OUTER_JOIN,其中需要INNER / LEFT_OUTER_JOIN。左连接仍然适用于Criterion#1,因为它受Value = ...的约束,因此与原始Inner Join没有实际区别。

// Prepare aliases (joins)
// -----------------------
if (searchCriteria.getSpecialId() != null || !StringUtils.isBlank(searchCriteria.getTitle())) {
    // Note: LEFT JOIN for both Special ID and Title,
    // since Hibernate Criteria API only allows 1 alias & join per Table (https://hibernate.atlassian.net/browse/HHH-879), and the 2nd criterion requires a Left Outer Join
    criteriaQuery.createAlias("specialTable", "st", JoinType.LEFT_OUTER_JOIN);                                                  
}
// ... All other aliases prepared ...

// Actual Criteria
// ... use the "st" single alias
© www.soinside.com 2019 - 2024. All rights reserved.