I am working on a Spring-MVC application in which the user can register products and productImages. Now there are 3 tables, User, Product, ProductImages. It is not always necessary to pull all the productImages until and unless the user explicitly goes into the product, where there is a modal, and the user can then select the images to load.
So I thought of using LazyLoading instead of EagerFetching. But I get lazyLoadException with that. So I opened a session manually in both Product and ProductImages, and I get a ObjectNotFound Exception. The problem is, productImages has a foreign key relation with product, so I must save product first before saving its images, and that is where I am having the problem. Kindly suggest me how to use lazy load in this situation. Error log and code goes below :
Error log :
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.WirTauschen.model.ProductImage#1150]
org.hibernate.internal.SessionFactoryImpl$1$1.handleEntityNotFound(SessionFactoryImpl.java:253)
com.WirTauschen.dao.ProductBasicDaoImpl.updateProduct(ProductBasicDaoImpl.java:50)
Controller :
@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;
}
The controller code shouldn't contain that much service side information, but this is just an attempt to make sure it works..I have defined LazyLoading in model, I can post the code if required, kindly tell me what am I doing wrong. Any pointers are welcome. Thank you for your time.
ALLthis issue will be resolved