LazyInitializationException Spring Boot - PullRequest
       4

LazyInitializationException Spring Boot

0 голосов
/ 18 декабря 2018

Я знаю, что есть много подобных тем, но я не могу понять из этих тем, как решить эту проблему.

У меня есть 3 класса: Автомобиль, Марка, Цвет.Автомобиль имеет только одну марку и список цветов.Марка имеет список автомобилей.Цвет не имеет никакого отношения.

Геттеры, сеттеры, ToString и конструкторы не предусмотрены для простоты.Я могу сохранить объекты в базе данных, и база данных уже заполнена.

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

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

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

@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<>();

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

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

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

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

Все работает очень хорошо, если я получаю как Eager, но я знаю, что это плохая практика, и вместо этого следует использовать Lazy loading,Но я продолжаю получать LazyInitializationException.

Из ошибки я понимаю, что требуется сеанс, но я не знаю, как его обеспечить, так как я работаю с Spring Data JPA, и там, где я должен объявить один ...

@SpringBootApplication
public class SrpingJpaApplication {

private static final Logger log = 
LoggerFactory.getLogger(SrpingJpaApplication.class);

public static void main(String[] args) {
    SpringApplication.run(SrpingJpaApplication.class, args);
}

@Bean
public CommandLineRunner demo(CarRepository carRepository,
                              ColorRepository colorRepository,
                              BrandRepository brandRepository) {
    return (args) -> {

        log.info("Reads all cars....");
        for (Car c : carRepository.findAll()) {
            System.out.println(c.toString());
        }

    };
}

}

Большое вам спасибо.

Отредактировано ----- >>>

Ошибка выдается в c.toString ();

Ошибка: вызвано: org.hibernate.LazyInitializationException: не удалось инициализировать прокси [com.readiness.moita.SrpingJPA.Models.Brand # 1] - нет сеанса

1 Ответ

0 голосов
/ 18 декабря 2018

Поскольку 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...