Spring Hibernate:尽管被配置,@Transactional在Spring Data JPA中不起作用 [英] Spring Hibernate: @Transactional is not working in Spring Data JPA despite being configured

查看:188
本文介绍了Spring Hibernate:尽管被配置,@Transactional在Spring Data JPA中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


LazyInitializationException:未能懒惰地初始化一个关系收集角色,无法初始化代理 - 无会话


我知道使用Eager获取类型可以正常工作,但这将是一个头痛和性能滞后于应用程序,所以,我必须继续考虑Lazy fetch类型。



我读到使用Spring Data JPA时, @Transactional 会初始化惰性关系,但它似乎对我没有影响。



这是我的应用程序的外观:



实体



课程实体
$ b

  @Entity 
@Table(name =course)
@Transactional

public class Course {


@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Intege r 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>学生们;

学生实体

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

@I $
@GeneratedValue(strategy = GenerationType.AUTO)
私人整数ID;

私人字符串名称;

私人字符串等级;

@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>培训班;

控制器

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

... 。

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

课程course = courseRepo.findById(6).get() ; (学生学生:
course.getStudents()){

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


}


ModelAndView modelAndView = new ModelAndView(redirect:list);

返回modelAndView;
}

}

存储库



课程库

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

学生资源库

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

Servlet配置文件

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

< context:annotation-config />

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

< mvc:annotation-driven />

...


< bean id =transactionManagerJPAclass =org.springframework.orm.jpa.JpaTransactionManager>
< property name =dataSourceref =myDataSource/>
< / bean>

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


< bean id =EMF
class =org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean>
< property name =packagesToScanvalue =com.company.springdemo.entity/>
< property name =dataSourceref =myDataSource/>

< property name =jpaProperties>
<道具>
< 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>
< /道具>
< / property>

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



我可能会做什么错误?

解决方案

我认为你在这里混淆了一些东西。

您有多个选择:
$ b


  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-层/


I have been receiving this error all the time when using Lazy evaluation in a ManyToMany relationship:

LazyInitializationException: failed to lazily initialize a collection of roles, could not initialize proxy - no Session

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:

  1. Access the relation within the transaction
  2. Use EAGER fetching
  3. Use custom queries with FETCH JOIN
  4. 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中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆