自我关系中的JPA Hibernate惰性负载收集

时间:2019-01-09 20:46:53

标签: java hibernate jpa

我试图以一种自恋的方式懒惰地装载产品的成分。产品可以包含零种或多种成分。该关系存储在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;

在我的Dao的方法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=?

但是,所有尝试都无法加载成分。他们只是返回一个空列表。 我用这种方法做错了什么? 我宁愿保持这种懒惰的关系。同样因为休眠,否则将返回cannot simultaneously fetch multiple bags,它引用了Product.orders和Product.ingredients

0 个答案:

没有答案