JPA Hibernate Ленивый сбор нагрузки в самоотношениях - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь лениво загрузить ингредиенты продукта в собственные отношения. Продукт может иметь ноль или более ингредиентов. Отношение сохраняется в сущности ProductComposition. Это мои сущности:

Продукт

@Entity(name = Product.TABLE_NAME)
//@NamedEntityGraph(name = "graph.Product.ingredients", attributeNodes = //@NamedAttributeNode("ingredients"))
public class Product {

    public static final String TABLE_NAME = "Product";

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long idProduct;

    private String name;

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE}, mappedBy = "product")
    private List<OrderDetail> orders;

    @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL, mappedBy = "ingredient", orphanRemoval=true)
    private List<ProductComposition> ingredients;

ProductComposition

@Entity(name = ProductComposition.TABLE_NAME)
@IdClass(ProductCompositionId.class)
public class ProductComposition {

    public static final String TABLE_NAME = "ProductComposition";

    @Id
    @ManyToOne //(fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "PrincipalProductID")
    private Product principalProduct;

    @Id
    @ManyToOne //(fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "IngredientID")
    private Product ingredient;

    private int quantity;

ProductCompositionId

class ProductCompositionId implements Serializable{

private long principalProduct;

private long ingredient;

В методе get моего Дао я пробовал разные вещи:

Получение с помощью CriteriaQuery ингредиентов и затем установка их на продукт

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<ProductComposition> q = cb.createQuery(ProductComposition.class);
Root<ProductComposition> product = q.from(ProductComposition.class);
product.fetch("principalProduct", JoinType.LEFT);
q.select(product).where(cb.equal(product.get("principalProduct"), id));     
List<ProductComposition> ingredients = entityManager.createQuery(q).getResultList();
Product p = entityManager.find(Product.class, id);
p.setIngredients(ingredients);

Использование Entity Graph

EntityGraph<Product> graph = (EntityGraph<Product>) entityManager.getEntityGraph("graph.Product.ingredients");
Map<String, Object> ingredients = new HashMap<>();
ingredients.put("javax.persistence.fetchgraph", graph);
Product p = entityManager.find(entityClass, id, ingredients);

Вызов метода initialize

p = productDao.get(p.getIdProduct()); //the get here just calls entityManager.find(Product.class, id)
Hibernate.initialize(p.getIngredients());
System.out.println("Ingredients size: "+p.getIngredients().size()); //gives 0

После вызова этих двух строк я получаю следующие два журнала, но p по-прежнему не содержит ингредиентов после:

    Hibernate: select product0_.idProduct as idProduc1_4_0_, product0_.name as name2_4_0_, orders1_.product_idProduct as product_3_3_1_, orders1_.foodOrder_idFoodOrder as foodOrde2_3_1_, orders1_.foodOrder_idFoodOrder as foodOrde2_3_2_, orders1_.product_idProduct as product_3_3_2_, orders1_.quantity as quantity1_3_2_, foodorder2_.idFoodOrder as idFoodOr1_2_3_, foodorder2_.CustomerID as Customer2_2_3_, foodorder2_.DeliverymanID as Delivery3_2_3_, foodorder2_.RestaurantID as Restaura4_2_3_ from Product product0_ left outer join OrderDetail orders1_ on product0_.idProduct=orders1_.product_idProduct left outer join FoodOrder foodorder2_ on orders1_.foodOrder_idFoodOrder=foodorder2_.idFoodOrder where product0_.idProduct=?
Hibernate: select ingredient0_.ingredient_idProduct as ingredie2_5_0_, ingredient0_.principalProduct_idProduct as principa3_5_0_, ingredient0_.ingredient_idProduct as ingredie2_5_1_, ingredient0_.principalProduct_idProduct as principa3_5_1_, ingredient0_.quantity as quantity1_5_1_, product1_.idProduct as idProduc1_4_2_, product1_.name as name2_4_2_ from ProductComposition ingredient0_ inner join Product product1_ on ingredient0_.principalProduct_idProduct=product1_.idProduct where ingredient0_.ingredient_idProduct=?

Однако, все попытки не могут загрузить ингредиенты. Они просто возвращают пустой список. Что я делаю не так в этих методах? Я бы предпочел, чтобы отношения были ленивыми. Кроме того, потому что в противном случае Hibernate вернет cannot simultaneously fetch multiple bags, ссылаясь на Product.orders и Product.ingredients

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...