JPA多线程下懒加载No session怎么处理及其解决及其代码
时间: 2023-12-05 13:04:26 浏览: 40
在多线程环境下使用 JPA 的懒加载可能会出现 No session 异常,这是因为每个线程都有自己的事务和数据库连接,当一个线程在一个事务中加载了一个实体并关闭了 session,另一个线程想要访问同一个实体时,由于没有 session,就会抛出 No session 异常。
解决这个问题的方法是使用 Open Session In View 模式,即在每个请求的处理中打开一个 session,并在请求结束后关闭它。这样可以保证每个请求都有一个有效的 session,从而避免 No session 异常。
以下是一个使用 Spring MVC 和 Hibernate 的例子:
首先,在 Spring 的配置文件中,配置 Hibernate 的 sessionFactory 和一个名为 openSessionInViewInterceptor 的拦截器:
```
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.example.model"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="openSessionInViewInterceptor" class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor"/>
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>
</bean>
```
然后,在 Controller 中使用 @Transactional 注解来开启事务,并在方法中访问实体:
```
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserRepository userRepository;
@RequestMapping("/{id}")
@Transactional
public String getUser(@PathVariable("id") Long id, Model model) {
User user = userRepository.findOne(id);
model.addAttribute("user", user);
return "user";
}
}
```
在这个例子中,每个请求都会打开一个 session,并在请求结束后关闭它,从而避免了 No session 异常。