2013-02-17 2 views
0

У меня есть следующие настройкикритерии API присоединиться к ленивой Коллекции

@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 
} 

Соединение beween этих классов только в одном направлении. Если двунаправленное соединение лучше (например, с точки зрения производительности)?

Как я могу запросить все элементы, которые были запущены после даты (startDate) и определенного продукта назначены?

Я пытаюсь реализации этого с критериями апи:

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. пункт списка, сессия или сессия не закрыты

Есть ли проблема с моим запросом или с ленивым списком товаров?

ответ

0

Это, вероятно, устарело, но у меня был код под рукой. Вот как я решаю это:

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 !!!!

Federico

+0

Сделайте это в любом производственном коде, и ваша производительность будет снижаться. Вы получаете несколько запросов. Итак, ваше решение работает. Это ужасное решение. Вам лучше писать свой собственный JPQL, используя API-интерфейс Criteria или Entity Graph. – harogaston

Смежные вопросы