【问题标题】:Criteria API join a lazy CollectionCriteria API 加入一个惰性集合
【发布时间】:2013-02-17 23:30:04
【问题描述】:

我有以下设置

@Entity
@Table(name = "Product")
public class Product implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String name;

    @OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
    private final List<Item> itemlist = new ArrayList<Item>();

    //some other attributes, getter/setter
}

@Entity
@Table(name = "Item")
public class Item implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private Date startDate;

    //some other attributes, getter/setter
}

这些类之间的连接只是单向的。如果双向连接更好(例如在性能方面)?

我如何查询在某个日期(startDate)之后启动并分配给特定产品的所有项目?

我尝试使用标准 api 来实现这一点:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Item> criteriaQuery = criteriaBuilder.createQuery(Item.class);
criteriaQuery = criteriaQuery.distinct(true);

Metamodel m = em.getMetamodel();
EntityType<Product> Product_ = m.entity(Product.class);
Root<Product> root = criteriaQuery.from(Product_);
Join join = root.join("itemlist");


Predicate condition = criteriaBuilder.equal(join.get("product"), selectedProduct);
criteriaQuery.where(condition);

criteriaQuery.select(join);

TypedQuery<Item> tq = em.createQuery(criteriaQuery);
System.out.println("result " + tq.getResultList());

我遇到了异常:

org.hibernate.LazyInitializationException: 延迟初始化角色集合失败:com.test.Product.itemlist,没有会话或会话被关闭

我的查询或惰性项列表有问题吗?

【问题讨论】:

    标签: hibernate collections lazy-loading criteria-api


    【解决方案1】:

    这可能是陈旧的,但我手头有代码。这就是我解决这个问题的方法:

        CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
        CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
        Root<Product> queryRoot = criteriaQuery.from(Product.class);
    
        Predicate idPredicate = criteriaBuilder.equal(queryRoot.get(Product_.id), id);
        criteriaQuery.where(idPredicate);
    
        TypedQuery<Product> typedQuery = em.createQuery(criteriaQuery);
    
        Product theProduct = typedQuery.getSingleResult();
    
        //this triggers the lazy relationship
        theProduct.getItemsList();
    

    HTH!!!!

    费德里科

    【讨论】:

    • 在任何生产代码中执行此操作,您的性能将付诸东流。您最终会遇到多个查询。因此,您的解决方案有效。这是一个可怕的解决方案。您最好使用 Criteria API 或实体图编写自己的 JPQL。
    猜你喜欢
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2018-02-27
    • 2011-02-13
    相关资源
    最近更新 更多