Hibernate Criteria:在子查询/DetachedCriteria 中执行 JOIN

发布于 2024-08-28 12:41:57 字数 3507 浏览 6 评论 0原文

我遇到了使用 DetachedCriteria 将 JOIN 添加到子查询的问题。代码大致如下:

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,但包含引发错误的别名

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?


@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

I'm running into an issue with adding JOIN's to a subquery using DetachedCriteria. The code looks roughly like this:

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

But the logged SQL does not contain the JOIN in the subquery, but does include the alias which is throwing an error

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
  )

How can I add the joins to the DetachedCriteria?


@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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泅渡 2024-09-04 12:41:57

您的代码中的以下行是否有拼写错误:

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

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

Don't you have a typo in your code at the following line :

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

I think, you should add this restriction on the subcriteria and not the criteria.

太阳男子 2024-09-04 12:41:57

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

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

If you need to join tables in subquery can you try make this. It is explicitly specifying joinType in your detached criteria.

subCriteria.createAlias("model.modelLanguages", "modelLang", CriteriaSpecification.LEFT_JOIN);
subCriteria.createAlias("modelLang.language", "lang", CriteriaSpecification.LEFT_JOIN);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文