如何使 OpenSessionInViewInterceptor 在 Spring mvc 中工作
How to make OpenSessionInViewInterceptor work in Spring mvc
我正在尝试在 spring mvc 中设置 OpenSessionInViewInterceptor 以修复:org.hibernate.LazyInitializationException:无法初始化代理 - 无会话。
下面是我已有的代码以及错误的来源。
AppConfig.java
@Configuration
@PropertySource("classpath:db.properties")
@EnableTransactionManagement
@ComponentScans(value = { @ComponentScan("com.debugger.spring.web.tests"), @ComponentScan("com.debugger.spring.web.service"), @ComponentScan("com.debugger.spring.web.dao"),
@ComponentScan("com.debugger.spring.web.controllers") })
public class AppConfig implements WebMvcConfigurer {
@Autowired
private Environment env;
@Bean
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
Properties props = new Properties();
// Setting JDBC properties
...
// Setting Hibernate properties
...
// Setting C3P0 properties
...
return factoryBean;
}
@Bean
public OpenSessionInViewInterceptor openSessionInViewInterceptor() {
OpenSessionInViewInterceptor openSessionInViewInterceptor = new OpenSessionInViewInterceptor();
openSessionInViewInterceptor.setSessionFactory(getSessionFactory().getObject());
return openSessionInViewInterceptor;
}
}
featured.jsp
<c:choose>
<c:when
test='${article.user.isSubscribed() and article.user.subscription.type eq "silver" }'>
<a class="bold"
href='${pageContext.request.contextPath}/u/${article.user.username}'><span
class="silvername"> <c:out value="${article.user.name}"></c:out></span></a>
</c:when>
<c:when
test='${article.user.isSubscribed() and article.user.subscription.type eq "gold" }'>
<a class="bold"
href='${pageContext.request.contextPath}/u/${article.user.username}'><span
class="goldname"> <c:out value="${article.user.name}"></c:out></span></a>
</c:when>
<c:when
test='${article.user.isSubscribed() and article.user.subscription.type eq "premium" }'>
<a class="bold"
href='${pageContext.request.contextPath}/u/${article.user.username}'><span
class="premiumname"> <c:out
value="${article.user.name}"></c:out></span></a>
</c:when>
<c:otherwise>
<a class="bold"
href='${pageContext.request.contextPath}/u/${article.user.username}'><span>
<c:out value="${article.user.name}"></c:out>
</span></a>
</c:otherwise>
</c:choose>
${article.user.isSubscribed()} 最有可能抛出错误,因为无法获取用户。我希望它 运行 不使用急切获取,我想我可以通过正确设置 OpenSessionInViewInterceptor 来实现它。
在您的配置中覆盖 WebMvcConfigurer#addInterceptors(InterceptorRegistry) class:
@Override
public void addInterceptors(InterceptorRegistry registry) {
OpenSessionInViewInterceptor openSessionInViewInterceptor = new OpenSessionInViewInterceptor();
openSessionInViewInterceptor.setSessionFactory(getSessionFactory().getObject());
registry.addWebRequestInterceptor(openSessionInViewInterceptor).addPathPatterns("/**");
}
同时在配置 class 上添加 @EnableWebMvc
。
回应OP的评论:
我不确定为什么它不起作用。我觉得一切都很好。还有另一种方法可以实现此目的:
设置hibernate.enable_lazy_load_no_trans
属性true
.
有关更多信息,请参阅 23.9.1. Fetching properties in Hibernate User Guide。
但这不是指南中所述的一个很好的选择:
Although enabling this configuration can make
LazyInitializationException
go away, it’s better to use a fetch plan
that guarantees that all properties are properly initialized before
the Session is closed.
In reality, you shouldn’t probably enable this setting anyway.
我正在尝试在 spring mvc 中设置 OpenSessionInViewInterceptor 以修复:org.hibernate.LazyInitializationException:无法初始化代理 - 无会话。
下面是我已有的代码以及错误的来源。
AppConfig.java
@Configuration
@PropertySource("classpath:db.properties")
@EnableTransactionManagement
@ComponentScans(value = { @ComponentScan("com.debugger.spring.web.tests"), @ComponentScan("com.debugger.spring.web.service"), @ComponentScan("com.debugger.spring.web.dao"),
@ComponentScan("com.debugger.spring.web.controllers") })
public class AppConfig implements WebMvcConfigurer {
@Autowired
private Environment env;
@Bean
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
Properties props = new Properties();
// Setting JDBC properties
...
// Setting Hibernate properties
...
// Setting C3P0 properties
...
return factoryBean;
}
@Bean
public OpenSessionInViewInterceptor openSessionInViewInterceptor() {
OpenSessionInViewInterceptor openSessionInViewInterceptor = new OpenSessionInViewInterceptor();
openSessionInViewInterceptor.setSessionFactory(getSessionFactory().getObject());
return openSessionInViewInterceptor;
}
}
featured.jsp
<c:choose>
<c:when
test='${article.user.isSubscribed() and article.user.subscription.type eq "silver" }'>
<a class="bold"
href='${pageContext.request.contextPath}/u/${article.user.username}'><span
class="silvername"> <c:out value="${article.user.name}"></c:out></span></a>
</c:when>
<c:when
test='${article.user.isSubscribed() and article.user.subscription.type eq "gold" }'>
<a class="bold"
href='${pageContext.request.contextPath}/u/${article.user.username}'><span
class="goldname"> <c:out value="${article.user.name}"></c:out></span></a>
</c:when>
<c:when
test='${article.user.isSubscribed() and article.user.subscription.type eq "premium" }'>
<a class="bold"
href='${pageContext.request.contextPath}/u/${article.user.username}'><span
class="premiumname"> <c:out
value="${article.user.name}"></c:out></span></a>
</c:when>
<c:otherwise>
<a class="bold"
href='${pageContext.request.contextPath}/u/${article.user.username}'><span>
<c:out value="${article.user.name}"></c:out>
</span></a>
</c:otherwise>
</c:choose>
${article.user.isSubscribed()} 最有可能抛出错误,因为无法获取用户。我希望它 运行 不使用急切获取,我想我可以通过正确设置 OpenSessionInViewInterceptor 来实现它。
在您的配置中覆盖 WebMvcConfigurer#addInterceptors(InterceptorRegistry) class:
@Override
public void addInterceptors(InterceptorRegistry registry) {
OpenSessionInViewInterceptor openSessionInViewInterceptor = new OpenSessionInViewInterceptor();
openSessionInViewInterceptor.setSessionFactory(getSessionFactory().getObject());
registry.addWebRequestInterceptor(openSessionInViewInterceptor).addPathPatterns("/**");
}
同时在配置 class 上添加 @EnableWebMvc
。
回应OP的评论:
我不确定为什么它不起作用。我觉得一切都很好。还有另一种方法可以实现此目的:
设置hibernate.enable_lazy_load_no_trans
属性true
.
有关更多信息,请参阅 23.9.1. Fetching properties in Hibernate User Guide。
但这不是指南中所述的一个很好的选择:
Although enabling this configuration can make
LazyInitializationException
go away, it’s better to use a fetch plan that guarantees that all properties are properly initialized before the Session is closed.In reality, you shouldn’t probably enable this setting anyway.