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); |