问题描述
我知道使用Eager获取类型可以正常工作,但这将是一个头痛和性能滞后于应用程序,所以,我必须继续考虑Lazy fetch类型。
我读到使用Spring Data JPA时,
您有多个选择:
$ b
- 访问交易中的关系
- 使用EAGER提取
- 对 FETCH JOIN使用自定义查询
- 使用投影
另请阅读我的文章以了解更多详情:
I have been receiving this error all the time when using Lazy evaluation in a ManyToMany relationship:
I know that using Eager fetch type will work fine, but this will be a headache and a performance lag to the application, so, I have to continue considering the Lazy fetch type.
I read that when using Spring Data JPA, @Transactional will initialize the lazy relations, but it doesn't seem to take effect with me.
Here is how my app look like:
Entities
Course Entity
@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;
Student Entity
@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
@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; }
}
Repositories
Course Repository
@Repository public interface CourseRepo extends JpaRepository<Course,Integer> {}
Student Repository
@Repository public interface StudentRepo extends JpaRepository<Student,Integer> { }
Servlet Configuration File
<?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>
What potentially could I be doing wrong?
I think you are mixing up things here. LazyInitializationException is popping up as you are trying to fetch the relation when the transaction is already over.
You have multiple choices:
- Access the relation within the transaction
- Use EAGER fetching
- Use custom queries with FETCH JOIN
- Use Projections
Also read my article for more details: https://blog.arnoldgalovics.com/2017/02/27/lazyinitializationexception-demystified/https://blog.arnoldgalovics.com/2017/03/14/using-projections-in-your-data-access-layer/
这篇关于Spring Hibernate:尽管被配置,@Transactional在Spring Data JPA中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!