在 Hibernate 中使用延迟加载而不是急切加载

In Hibernate using Lazy loading instead of eager loading

我正在开发一个 Spring-MVC 应用程序,用户可以在其中注册产品和产品图像。现在有 3 个表,User、Product、ProductImages。并不总是需要拉取所有 productImages 直到并且除非用户明确进入产品,那里有一个模式,然后用户可以 select 要加载的图像。

所以我想到了使用 LazyLoading 而不是 EagerFetching。但是我得到了 lazyLoadException 。因此,我在 Product 和 ProductImages 中手动打开了一个会话,并且出现了 ObjectNotFound 异常。问题是,productImages 与产品有外键关系,所以我必须先保存产品,然后再保存其图像,这就是我遇到问题的地方。请建议我如何在这种情况下使用延迟加载。错误日志和代码如下:

错误日志:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.WirTauschen.model.ProductImage#1150]
    org.hibernate.internal.SessionFactoryImpl.handleEntityNotFound(SessionFactoryImpl.java:253)
com.WirTauschen.dao.ProductBasicDaoImpl.updateProduct(ProductBasicDaoImpl.java:50)

控制器:

 @RequestMapping(value = "/product/addimages", method = RequestMethod.POST)
    public @ResponseBody String addProductImages(@RequestParam("productImages") MultipartFile[] uploadedFiles){

    if(uploadedFiles != null && uploadedFiles.length>0) {
        for (MultipartFile uploadedFile : uploadedFiles) {
            try {
                if (!(uploadedFile.isEmpty())) {
                    imagesList.add(uploadedFile.getBytes());
                }
            } catch (IOException e) {
                e.printStackTrace();
                return "image failed to upload";
            }
        }
    }
   return "done";
}



@RequestMapping(value="/product/add",method = RequestMethod.POST)
    public String addProduct(@ModelAttribute("product") ProductBasic productBasic,Model model){
        model.addAttribute("product", new ProductBasic());
        productBasic.setProductimage(productprofileimage);
      int productid = productBasicService.addProduct(productBasic);
        ProductBasic productBasic1 = this.productBasicService.getProductById(productid);
            for (int index = 0; index < imagesList.size(); index++) {
                if (index == 0) {
                    productBasic1.setProductimage(imagesList.get(0));
                }
                ProductImage productImage = new ProductImage();
                productImage.setProductimage(imagesList.get(index));
                this.productImageService.addProductImage(productBasic1, productImage);
            }
            productBasicService.updateProduct(productBasic1);
           imagesList.clear();
        productprofileimage =null;
        return "redirect:/product/show";
    }

ProductDAOImpl :

@Override
    @Transactional
    public int addProduct(User user, ProductBasic productBasic) {
// I was using getSessionBefore with Eager, it worked, thought of trying openSession
        session = this.sessionFactory.openSession();
        user.getProductBasics().add(productBasic);
        productBasic.setUser1(user);
        session.save(productBasic);
        System.out.println("Returned product information is"+productBasic.getProductid());
        session.flush();
        //session.close();
        return productBasic.getProductid();
    }

 @Override
    @Transactional
    public void updateProduct(User user,ProductBasic productBasic) {
        logger.debug("Editing product information");
        session = this.sessionFactory.getCurrentSession();
      //  User user1 = (User) session.get(User.class,id);
        user.getProductBasics().add(productBasic);
        productBasic.setUser1(user);
        session.saveOrUpdate(productBasic);
        session.flush();
    }

ProductImageDAOImpl :

@Override
    @Transactional
    public boolean addProductImage(ProductBasic productBasic,ProductImage productImage) {
            session = sessionFactory.openSession();
            productBasic.getProductImageSet().add(productImage);
            productImage.setProductimageupload(productBasic);
            productBasic.setImagecount((productBasic.getImagecount()+1));
            session.merge(productBasic);
            session.saveOrUpdate(productImage);
            return true;

    }

控制器代码不应该包含那么多服务端信息,但这只是为了确保它能正常工作。我已经在模型中定义了 LazyLoading,如果需要,我可以 post 代码,请告诉我我做错了什么。欢迎任何指点。感谢您的时间。

扩展我的评论

  1. 去掉上面的saveOrUpdate。
  2. 将级联类型更改为ALL

PS:您在 UpdateProduct 方法中遇到异常。但是您已经发布了 addProduct 的代码。