Spring Hibernate: @Transactional не работает в Spring Data JPA, несмотря на то, что настроен - PullRequest
0 голосов
/ 27 мая 2018

Я все время получал эту ошибку при использовании отложенной оценки в отношении ManyToMany:

LazyInitializationException: не удалось лениво инициализировать коллекцию ролей, не удалось инициализировать прокси - нет сеанса

Я знаю, что использование типа извлечения Eager будет работать нормально, но это будет головной болью и отставанием производительности приложения, поэтому я должен продолжить рассмотрение типа извлечения Lazy.

Я читал, что при использовании Spring Data JPA @Transactional инициализирует ленивые отношения, но, похоже, со мной это не вступает в силу.

Вот как выглядит мое приложение:

Сущности

Субъект курса

@Entity
@Table(name = "course")
@Transactional
public class Course {


@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

@Column(name = "course_name")
private String courseName;

@Column(name = "course_description")
private String courseDescription;

@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.DETACH,CascadeType.REFRESH,CascadeType.PERSIST})
@JoinTable(
        name = "course_student",
        joinColumns = @JoinColumn(name = "course_id"),
        inverseJoinColumns = @JoinColumn(name = "student_id") )
private List<Student> students;

Субъект студента

@Entity
@Table(name = "students")
public class Student {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

private String name;

private String grade;

@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.DETACH,CascadeType.REFRESH,CascadeType.PERSIST},fetch = FetchType.EAGER)
@JoinTable(
        name = "course_student",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id") )
List<Course> courses;

Контроллер

@Controller
@RequestMapping("/courses")
@Transactional
public class CourseController {

....

@GetMapping("get-joined-students")
ModelAndView getJoined() {

    Course course = courseRepo.findById(6).get();

    for (Student student :
            course.getStudents()) {

        System.out.println("Student: " + student);
    }


    ModelAndView modelAndView = new ModelAndView("redirect:list");

    return modelAndView;
}

}

Хранилища

Репозиторий курсов

@Repository
public interface CourseRepo extends JpaRepository<Course,Integer> {}

Репозиторий студентов

@Repository
public interface StudentRepo extends JpaRepository<Student,Integer> { }

Файл конфигурации сервлета

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  ....    >

<context:annotation-config/>

<context:component-scan base-package="com.company.springdemo"/>

<mvc:annotation-driven/>

....

<jpa:repositories transaction-manager-ref="transactionManagerJPA" base-package="com.company.springdemo" entity-manager-factory-ref="EMF" />

<bean id="transactionManagerJPA" class="org.springframework.orm.jpa.JpaTransactionManager" >
    <property name="dataSource" ref="myDataSource" />
</bean>

<tx:annotation-driven transaction-manager="transactionManagerJPA" />


<bean id="EMF"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="packagesToScan" value="com.company.springdemo.entity" />
    <property name="dataSource" ref="myDataSource" />

    <property name="jpaProperties">
        <props>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.format_sql">true</prop>
        </props>
    </property>

    <property name="persistenceProvider">
        <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
    </property>
</bean>

Что потенциально я могу делать не так?

Ответы [ 2 ]

0 голосов
/ 13 ноября 2018

Использование @Transactional ни для каких общедоступных методов требует зависимости aspectj.В коде связанный метод выглядит как приватный пакет.Надеюсь, переход на общественное мнение должен решить проблему.У меня была такая же проблема, и этот пост помогает мне Атрибут Spring @Transactional работает с закрытым методом?

0 голосов
/ 27 мая 2018

Я думаю, что вы тут все путаете.LazyInitializationException появляется, когда вы пытаетесь получить отношение, когда транзакция уже завершена.

У вас есть несколько вариантов:

  1. Доступ к отношению в транзакции
  2. Использовать выборку EAGER
  3. Использовать пользовательские запросы с FETCH JOIN
  4. Использовать проекции

Также читайте мою статью для получения более подробной информации: https://blog.arnoldgalovics.com/2017/02/27/lazyinitializationexception-demystified/https://blog.arnoldgalovics.com/2017/03/14/using-projections-in-your-data-access-layer/

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