【问题标题】:Hibernate criteria join table issue休眠条件连接表问题
【发布时间】:2017-09-25 15:42:18
【问题描述】:

如下所示,我有 3 个实体。我想编写一个获取产品的查询。在此查询中,参数是 optionValues id 的列表。

现在我的问题是如何加入这些实体?

产品:

 public class Product{
   //other col

    @OneToMany(mappedBy = "product")
    private Set<Attribute> attributeSet = new HashSet<>();
 }

属性:

public class Attribute{
  @OneToOne
  @JoinColumn(name = "OPTION_VALUE_ID")
  private OptionValue optionValue;

  @ManyToOne
  @JoinColumn(name="PRODUCT_ID",referencedColumnName="id")
  private Product product;
}

optionValue:

 public class OptionValue{
     @Column(name = "id")
     private Long id;

    @Column(name = "value",updatable = true)
    private String value;
 }

我写了一个查询,但我认为我的代码不是一个好的解决方案。

 Criteria aCriteria = null;
    if (!optionValueList.isEmpty()) {
        aCriteria = currentSession().createCriteria(Attribute.class, "attribute");
        aCriteria.createAlias("attribute.optionValue", "optionValue");
        aCriteria.add(Restrictions.in("optionValue.id", optionValueList));
        attributes = aCriteria.list();
    }
    PagingData<Product> pagingData = new PagingData<>();
    Criteria criteria = currentSession().createCriteria(Product.class, "product");
    if (!attributes.isEmpty()) {
        for (Attribute attribute:attributes){
            longList.add(attribute.getId());
        }
        criteria.createAlias("product.attributeSet", "attribute");
        criteria.add(Restrictions.in("attribute.id", longList));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

    }

【问题讨论】:

  • 你能告诉我们这些类的完整代码吗?以及对应表的定义?您写道,输入是属性 ID 列表,但类 Attribute 没有这样的成员/映射到列。
  • @JavaGuynextdoor,对不起 :(。optionValueList 而不是attribute ID。

标签: java hibernate hibernate-criteria jointable


【解决方案1】:

一般的想法是从创建要返回的对象的标准开始,然后通过添加连接的标准来进一步发展。所以我从Parent 类开始,添加限定符,最后是嵌套最多的元素OptionValue

下面的代码未经测试,但你应该明白了:

Criteria criteria = currentSession()
  .createCriteria(Product.class)
  .createCriteria("attributeSet", "join_between_product_and_attribute");

if (!attributes.isEmpty()) {
  Set<String> attributeIds = new HashSet<>();
  for (Attribute attribute : attributeList) {
    attributeIds.add(attribute.getId());
  }
  criteria.add(Restrictions.in("id", attributeIds));
}

criteria = criteria.createCriteria("optionValue", "join_between_attribute_optionvalue");
if (!optionValueList.isEmpty()) {
  criteria.add(Restrictions.in("id", optionValueList));
}

【讨论】:

  • 感谢您的回答。我没有attributes ID。你的解决方案如何得到它?
  • 当您加入attributeSet 时,您的条件开始引用属性。每个属性都有一个id,不是吗?您自己的示例还引用了属性 ID。我建议先尝试这段代码,然后返回你得到的错误(如果有的话)。
  • 我只有optionValue ID。正如您在我的回答中看到的,我通过criteria 查询获取它。
【解决方案2】:

更简单的解决方案是使用CriteriaQuery。我没有测试以下代码,但我认为它应该可以正常工作。它需要休眠 5,但也适用于休眠 4 中的一些修改:

CriteriaBuilder cb = sessionFactory.getCriteriaBuilder();
CriteriaQuery<Product> query = cb.createQuery(Product.class);
Root<Product> r = query.from(Product.class);

In<Object> in = cb.in(r.join("attributeSet ").join("optionValue").get("id"));
for(Object optionValue : optionValueList){
    in.value(optionValue);
}
query.select(r).where(in);

return sessionFactory.getCurrentSession().createQuery(query).getResultList();

我假设您可以访问optionValueList,因为您在问题中发布了它。

对于EntityManager 的解决方案,我假设您已经能够实例化一个。

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> query = cb.createQuery(Product.class);
Root<Product> r = query.from(Product.class);

In<Object> in = cb.in(r.join("attributeSet ").join("optionValue").get("id"));
for(Object optionValue : optionValueList){
    in.value(optionValue);
}
query.select(r).where(in);

return entityManager.createQuery(query).getResultList();

如果您有EntityManagerFactory,请将第一个entityManager 替换为entityManagerFactory.createEntityManager(),将第二个替换为entityManagerFactory.createEntityManager()

【讨论】:

  • 感谢您的回答。在此查询中在哪里使用optionValueList?对于getCriteriaBuilder,我应该使用entityManager吗?
  • stackoverflow.com/a/9323183/7109162 这是一个在右边使用的例子。我自己没用过。明天更新答案。如果您有entityManager,它也应该可以工作。代码可能与我的不同
  • 非常感谢 :)
  • @ali 已更新。如果你想要一个带有 entityManager 的版本,我可以开发一个
  • 谢谢。是的,我真的很想。我会接受的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 2016-06-16
相关资源
最近更新 更多