2

I am using Spring framework and hibernate , i mapping @OneToMany in it , when i load Category to create new product , i get Error failed to lazily initialize a collection with mapping in hibernate, i have previously seen some instructions that please remove FectType.Lazy and I have done so but still have no effect

Category.java

package com.techzone.springmvc.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

@Entity
@Table(name = "categorys")
public class Category implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @NotNull
    @Column(name = "name")
    private String name;

    @OneToMany(mappedBy = "category" , cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH} , fetch = FetchType.LAZY)
    private Set <Product> products = new HashSet<>();

    public Category() {

    }

    public Category(String name, Set<Product> products) {
        super();
        this.name = name;
        this.products = products;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Product> getProducts() {
        return products;
    }

    public void setProducts(Set<Product> products) {
        this.products = products;
    }

    @Override
    public String toString() {
        return "Category [id=" + id + ", name=" + name + ", products=" + products + "]";
    }



}

Product.java

package com.techzone.springmvc.entity;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

@Entity
@Table(name = "products")
public class Product implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;


    @Size(max = 65)
    @NotNull
    @Column(name = "name")
    private String name;

    @Column(name = "price")
    private long price;

    @Column(name = "inventory")
    private long inventory;

//  @OneToOne(fetch = FetchType.LAZY , cascade = CascadeType.ALL)
//  @JoinColumn(name = "productDetail_id")
//  private ProductDetail productDetail;

    // test
    @OneToOne(mappedBy = "product" , cascade = CascadeType.ALL , fetch = FetchType.LAZY)
    private ProductDetail productDetail;


    @ManyToOne(cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH}, fetch = FetchType.EAGER , optional = false)
    @JoinColumn(name = "category_id" , nullable = false)
    private Category category;

    @ManyToOne(cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH} , optional = false)
    @JoinColumn(name = "brand_id" , nullable = false)
    private Brand brand;

    @ManyToOne(cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH} , optional = false)
    @JoinColumn(name = "sale_id" , nullable = false)
    private Sale sale;

    public Product() {

    }


    public Product(String name, long price, long inventory, ProductDetail productDetail, Category category,
            Brand brand, Sale sale) {
        super();
        this.name = name;
        this.price = price;
        this.inventory = inventory;
        this.productDetail = productDetail;
        this.category = category;
        this.brand = brand;
        this.sale = sale;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getPrice() {
        return price;
    }

    public void setPrice(long price) {
        this.price = price;
    }

    public long getInventory() {
        return inventory;
    }

    public void setInventory(long inventory) {
        this.inventory = inventory;
    }

    public ProductDetail getProductDetail() {
        return productDetail;
    }

    public void setProductDetail(ProductDetail productDetail) {
        this.productDetail = productDetail;
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    public Brand getBrand() {
        return brand;
    }

    public void setBrand(Brand brand) {
        this.brand = brand;
    }

    public Sale getSale() {
        return sale;
    }

    public void setSale(Sale sale) {
        this.sale = sale;
    }

    @Override
    public String toString() {
        return "Product [id=" + id + ", name=" + name + ", price=" + price + ", inventory=" + inventory
                + ", productDetail=" + productDetail + ", category=" + category + ", brand=" + brand + ", sale=" + sale
                + "]";
    }


} // End Class //

Im using JpaRepository

@Repository("categoryRepository")
public interface CategoryRepository extends JpaRepository<Category,Integer>{


}
public interface CategoryService {

    public Category getCategory(int theId) throws ResourceNotFoundException;

    public List<Category> getCategorys();

    public void saveCategory(Category theCategory);

    public void deleteCategory(int theId);

}
@Service
//@PersistenceContext(type = PersistenceContextType.EXTENDED)
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryRepository categoryRepository;

    @Override
    @Transactional
    public Category getCategory(int theId) throws ResourceNotFoundException {
        return categoryRepository.findById(theId).orElseThrow(()-> new ResourceNotFoundException(theId));
    }

    @Override
    @Transactional
    public List<Category> getCategorys() {
        return categoryRepository.findAll();
    }

    @Override
    @Transactional
    public void saveCategory(Category theCategory) {
        categoryRepository.save(theCategory);

    }

    @Override
    @Transactional
    public void deleteCategory(int theId) {
        categoryRepository.deleteById(theId);

    }

}

Here is code at controller

    @Autowired
    private CategoryService categoryService;
    //================ TEST SUPPORT ===============//
    public void getDependencyForProductProcess(Model theModel) {
        List<Category> categorys = categoryService.getCategorys();
        for (int i = 0 ; i < categorys.size() ; i++) {
            System.out.println(categorys.get(i).getName());
        }
     theModel.addAttribute("categorys", categorys);

    }
    //================ TEST SUPPORT ===============//

    @GetMapping("/showForm")
    public String showFormAddProduct(Model theModel) {

        LOG.debug("inside show customer-form handler method");

        Product theProduct = new Product();
        theModel.addAttribute("productModel", theProduct);
        getDependencyForProductProcess(theModel);
        return "product-form";
    }

product-form.jsp

<form:form method="post" action="save?${_csrf.parameterName}=${_csrf.token}" modelAttribute="productModel"  class="form-horizontal" enctype="multipart/form-data">
            <form:input path="id" type="hidden" />
            <div class="form-group">
                <label class="control-label col-sm-4" for="product.productname">Name Product</label>
                <div class="col-sm-4">
                    <form:input path="name" type="text" class="form-control" id="name" name="name" placeholder="Enter name of product" />
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-sm-4" for="product.price">Price Product</label>
                <div class="col-sm-4">
                    <form:input path="price" type="text" class="form-control" id="price" name="price" placeholder="Enter code of product" />
                </div>
            </div>

            <div class="form-group">
                <label class="control-label col-sm-4" for="product.inventory">Inventory</label>
                <div class="col-sm-4">
                    <form:input path="inventory" type="text" class="form-control" id="inventory" name="inventory" placeholder="Enter inventory" />
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-sm-4" for="category">Category</label>
                <div class="col-sm-4">
                    <form:select path="category.id" class="form-control input-sm">
                        <form:option value="-1" label="--- Select ---" />
                        <form:options items="${categorys}" itemValue="id" />
                    </form:select>
                </div>
            </div>

            <div class="form-group">
                <div class="col-sm-offset-4 col-sm-6">
                    <button type="submit" class="btn btn-success">Save</button>
                    <button type="button" onclick="location.href='./'"class="btn btn-defaulf">Cancel</button>
                </div>
            </div>
        </form:form>

but i get error

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.techzone.springmvc.entity.Category.products, could not initialize proxy - no Session

"I don't know where it was wrong, i want to show list category to add a product but error at"

<form:options items="${categorys}" itemValue="id" />'

"if anyone knows please help me and I appreciate it!"

4
  • show the code in which you fetch the collection Commented Aug 3, 2019 at 7:04
  • Hello Maciej Kowalski , very happy with your suggestion. I had improve info detail code as above. Please help me problem if you know it , very thank! Commented Aug 3, 2019 at 7:48
  • You try to load products in one Category without a transaction. With exactly your mapping, I had the same error. By changing the Category entity, fetching egarly the products, i am able to retrieve the products of one category. Change your Category entity with that : @OneToMany(mappedBy = "category" , cascade = {CascadeType.ALL} , fetch = FetchType.EAGER) private Set<Product> products = new HashSet<>(); Commented Aug 3, 2019 at 15:03
  • Thank you Gorgui Ndong , but in the real problem , fetchType.EAGER very terrible if you have many category , EAGER will retrieve all product related , in my case i just want fetchType.LAZY working for me Commented Aug 3, 2019 at 15:42

1 Answer 1

2

load eagarly the products is not good for the performance. Another solution is to keep your transaction opened during your query. I see that you have @Transactional in your CategoryServiceImpl methods but not in your controller. you can have more details in this post : lazyinitializationexception

Sign up to request clarification or add additional context in comments.

1 Comment

i had fixed this error by way remove toString method in Category.java , because if any have a category don't have product, load product in toString will be fail. Thank everybody!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.