LazyInitializationException Spring Boot

时间:2018-12-18 15:56:58

标签: java spring spring-data-jpa

我知道那里有很多类似的线程,但是我无法从那些线程中弄清楚如何克服这个问题。

我有3类汽车,品牌,颜色。 一辆汽车只有一个品牌和一系列颜色。 品牌有汽车清单。 颜色没有任何关系。

为简单起见,未提供字母,设置器,ToString和构造函数。 我能够将对象保存到数据库中,并且数据库已经填充。

--------------------------------------------------- ---------------------------------

  ===================================================================
  group1        group2         meandiff     lower      upper     reject
   ---------------------------------------------------------------------
    A              B            13.8883      12.493    15.2835   True 
    A              C            10.2884      8.5795    11.9972   True 

--------------------------------------------------- ---------------------------------

===================================================================
  group1        group2  group3       meandiff     lower      upper     reject
   ---------------------------------------------------------------------
 A               B        C            13.8883     12.493    15.2835   True

--------------------------------------------------- ---------------------------------

@Entity
@Table(catalog = "spring_project")
public class Car {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String model;

@ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable( name = "car_color", catalog = "spring_project",
            joinColumns         = { @JoinColumn(name = "car_id") },
            inverseJoinColumns  = { @JoinColumn(name = "colors_id") }
)
private List<Color> colors = new ArrayList<>();

@ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name="brand_id", referencedColumnName="id")
private Brand brand;

--------------------------------------------------- ---------------------------------

如果我像Eager一样抓取一切,一切都会很好,但是我知道这是一个坏习惯,应该使用惰性加载代替。但是我一直收到LazyInitializationException。

我从错误中了解到需要一个会话,但是自从我使用Spring Data JPA以来,我都不知道如何提供会话。

@Entity
@Table(catalog = "spring_project")
public class Brand {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@OneToMany(mappedBy = "brand", fetch = FetchType.LAZY)
private List<Car> cars = new ArrayList<>();

}

非常感谢您。

已编辑----- >>>

在c.toString()上引发错误;

错误:原因:org.hibernate.LazyInitializationException:无法初始化 代理[com.readiness.moita.SrpingJPA.Models.Brand#1]-无会话

1 个答案:

答案 0 :(得分:4)

由于FetchType中的Brand是惰性的,因此不会通过调用fetchAll()将其自动加载到会话中。要使其自动加载到会话中,您需要:

更改

@ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name="brand_id", referencedColumnName="id")
private Brand brand;

@ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.EAGER)

Ex

@ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="brand_id", referencedColumnName="id")
private Brand brand;

如果不想将获取类型设置为eager,则需要将对toString的调用移至服务方法Ex

@Component
public CarService implements ICarService {

    @Autowired
    CarRepository carRepository;

    @Transactional
    public void printAllCars() {
        for (Car c : carRepository.findAll()) {
            System.out.println(c.toString());
        }
    }   
}

然而,正确的方法是编写条件查询或hql