首页 > 解决方案 > LazyInitializationException 未初始化代理 - 无会话

问题描述

我正在使用 Spring 框架和休眠,我在其中映射 @OneToMany,当我加载 Category 以创建新产品时,我得到错误 failed to lazily initialize a collection with mapping in hibernate,我以前看过一些说明,请删除 FectType.Lazy我已经这样做了,但仍然没有效果

类别.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 + "]";
    }



}

产品.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 //

我正在使用 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);

    }

}

这是控制器的代码

    @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";
    }

产品-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>

但我得到错误

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

“我不知道错在哪里,我想显示列表类别以添加产品,但错误在”

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

“如果有人知道,请帮助我,我很感激!”

标签: hibernate

解决方案


过度加载产品对性能不利。另一种解决方案是在查询期间保持交易打开。我看到您的 CategoryServiceImpl 方法中有 @Transactional ,但控制器中没有。您可以在这篇文章中了解更多详细信息:lazyinitializationexception


推荐阅读