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

时间:2018-09-16 22:55:51

标签: hibernate hibernate-criteria

我正在使用Hibernate来实现“搜索”页面,在其中可能会使用或可能不会使用不同的条件。一个标准是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

有解决方案吗?我的别名不同,但仍然无法使用。

1 个答案:

答案 0 :(得分:0)

这是一个古老的Hibernate错误-https://hibernate.atlassian.net/browse/HHH-879-自2005年以来仍处于打开状态!

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

我要解决的问题是定义一个通用的LEFT_OUTER_JOIN,其中需要INNER / LEFT_OUTER_JOIN。左联接仍然适用于准则1,因为它受Value = ...约束,因此与原始的内部联接没有真正的区别。

// 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