关于java:Hibernate Criteria:在Subquery / DetachedCriteria中执行JOIN

Hibernate Criteria: Perform JOIN in Subquery/DetachedCriteria

我在使用DetachedCriteria将JOIN添加到子查询时遇到问题。 该代码大致如下所示:

1
2
3
4
5
6
7
8
9
10
Criteria criteria = createCacheableCriteria(ProductLine.class,"productLine");
criteria.add(Expression.eq("productLine.active","Y"));

DetachedCriteria subCriteria = DetachedCriteria.forClass(Model.class,"model");
subCriteria.setProjection(Projections.rowCount());
subCriteria.createAlias("model.modelLanguages","modelLang");
subCriteria.createAlias("modelLang.language","lang");
criteria.add(Expression.eq("lang.langCode","EN"));
subCriteria.add(Restrictions.eqProperty("model.productLine.productLineId","productLine.productLineId"));
criteria.add(Subqueries.lt(0, subCriteria));

但是记录的SQL在子查询中不包含JOIN,但是包含了引发错误的别名。

1
2
3
4
5
6
7
8
9
SELECT *
FROM PRODUCT_LINE this_
WHERE this_.ACTIVE=?
AND ?                  <
  (SELECT COUNT(*) AS y0_
  FROM MODEL this0__
  WHERE lang3_.LANG_CODE      ='EN'
  AND this0__.PRODUCT_LINE_ID     =this_.ID
  )

如何将联接添加到DetachedCriteria?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
@Entity
@Table(name ="PRODUCT_LINE")
public class ProductLine implements java.io.Serializable {

    private long productLineId;
    private char active;
    private Set<Models> models = new HashSet<Models>(0);

    @OneToMany(fetch = FetchType.LAZY, mappedBy ="productLine")
    public Set<Models> getModels() {
        return this.models;
    }

}

@Entity
@Table(name ="MODEL")
public class Model implements java.io.Serializable {

    private long modelId;
    private ProductLine productLine;
    private String name;
    private Set<ModelLanguages> modelLanguages = new HashSet<ModelLanguages>(0);

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name ="PRODUCT_LINE_ID")
    public ProductLine getProductLine() {
        return this.productLine;
    }

    @Column(name ="NAME", nullable = false)
    public String getName() {
        return this.name;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy ="model")
    public Set<ModelLanguages> getModelLanguages() {
        return this.modelLanguages;
    }

}

@Entity
@Table(name ="MODEL_LANGUAGES")
public class ModelLanguages implements java.io.Serializable {

    private long id;
    private Language language;
    private Model model;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name ="LANGUAGE_ID", nullable = false, insertable = false, updatable = false)
    public Language getLanguage() {
        return this.language;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name ="MODEL_ID", nullable = false, insertable = false, updatable = false)
    public Model getModel() {
        return this.model;
    }
}


@Entity
@Table(name ="LANGUAGES", uniqueConstraints = @UniqueConstraint(columnNames ="LANG_CODE"))
public class Language implements java.io.Serializable {

    private long languageId;
    private String langCode;
    private Set<ModelLanguages> modelLanguages = new HashSet<ModelLanguages>(
            0);

    @Column(name ="LANG_CODE", unique = true, nullable = false)
    public String getLangCode() {
        return this.langCode;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy ="language")
    public Set<ModelLanguages> getModelLanguages() {
        return this.modelLanguages;
    }
}

Hibernate version: 3.2.6.ga
Hibernate core: 3.3.2.GA
Hibernate annotations: 3.4.0.GA
Hibernate commons-annotations: 3.3.0.ga
Hibernate entitymanager: 3.4.0.GA
Hibernate validator: 3.1.0.GA


您在下面的代码行中没有错字:

1
criteria.add(Expression.eq("lang.langCode","EN"));

我认为,您应该在子条件而不是条件上添加此限制。


如果您需要在子查询中联接表,可以尝试这样做。 它是在分离条件中显式指定joinType。

1
2
subCriteria.createAlias("model.modelLanguages","modelLang", CriteriaSpecification.LEFT_JOIN);
subCriteria.createAlias("modelLang.language","lang", CriteriaSpecification.LEFT_JOIN);