Java 访问共享同一PersistentSet的两个对象是否导致没有会话或会话已关闭?
刚刚启动了一个项目,该项目具有以前开发人员提供的奇怪数据库设计。我已经找到了解决这个问题的方法。但是我想听听其他人为什么会这样,因为OpenSessionInViewFilter是在web.xml中配置的,并且可以在延迟加载集上正常工作,除了这种情况。下面是真实代码的修改版本,用于解释该场景 我能想到的唯一一件事是,在这个例子中,两种蛋白质对同一个集合有相同的引用,该集合与ncbiGI编号66275854相连。有没有人遇到过类似的问题并知道原因 Protein.javaJava 访问共享同一PersistentSet的两个对象是否导致没有会话或会话已关闭?,java,spring,hibernate,lazy-loading,Java,Spring,Hibernate,Lazy Loading,刚刚启动了一个项目,该项目具有以前开发人员提供的奇怪数据库设计。我已经找到了解决这个问题的方法。但是我想听听其他人为什么会这样,因为OpenSessionInViewFilter是在web.xml中配置的,并且可以在延迟加载集上正常工作,除了这种情况。下面是真实代码的修改版本,用于解释该场景 我能想到的唯一一件事是,在这个例子中,两种蛋白质对同一个集合有相同的引用,该集合与ncbiGI编号66275854相连。有没有人遇到过类似的问题并知道原因 Protein.java @Entity @Tab
@Entity
@Table(name = "Protein")
public class Protein implements Serializable {
private static final long serialVersionUID = 8578992962633035166L;
private static Log logger = LogFactory.getLog(Protein.class);
Long id;
String ncbiName;
String ncbiGI;
Set<WhOrtholog> whOrthologs;
@Id
@Column(name = "ProteinId")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "NCBIProteinGI")
public String getNcbiGi() {
return ncbiGI;
}
public void setNcbiGI(String ncbiGI) {
this.ncbiGI = ncbiGI;
}
@OneToMany(fetch = FetchType.LAZY, targetEntity = WhOrtholog.class)
@JoinColumn(name = "NCBIPROTEINGI", referencedColumnName = "NCBIPROTEINGI", updatable = false, insertable = false)
public Set<WhOrtholog> getWhOrthologs() {
return whOrthologs;
}
public void setWhOrthologs(Set<WhOrtholog> whOrthologs) {
this.whOrthologs = whOrthologs;
}
}
TestController.java
@Controller
@RequestMapping(value = "/test.html")
public class TestController {
@Resource
private LookupService lookupService;
@RequestMapping(params = "method=test")
public void testSameWhOrthologSet(HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException {
Protein mainProtein = lookupService.findProteinById(3635595L);
Protein secondProtein = lookupService.findProteinById(2486174L);
// exception on calling mainProtein.getWhOrthologs()
for (WhOrtholog whOrtholog : mainProtein.getWhOrthologs()) {
// do my normal process
}
}
public LookupService getLookupService() {
return lookupService;
}
public void setLookupService(LookupService lookupService) {
this.lookupService = lookupService;
}
}
LookupService.java
public Protein findProteinById(Long proteinId) {
return lookupDao.getProteinById(proteinId);
}
java
public Protein getProteinById(Long proteinId) {
Protein protein = (Protein) getSessionFactory().getCurrentSession().get(Protein.class, proteinId);
return protein;
}
异常堆栈跟踪
[15:22:19][DEBUG] [org.springframework.orm.hibernate3.support.OpenSessionInViewFilter] Closing single Hibernate Session in OpenSessionInViewFilter
[15:22:19][DEBUG] [org.springframework.orm.hibernate3.support.OpenSessionInViewFilter] Closing single Hibernate Session in OpenSessionInViewFilter
[15:22:19][DEBUG] [org.springframework.orm.hibernate3.support.OpenSessionInViewFilter] Closing single Hibernate Session in OpenSessionInViewFilter
[15:22:19][DEBUG] [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
[15:22:19][DEBUG] [org.hibernate.jdbc.ConnectionManager] transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
Feb 04, 2016 3:22:19 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [springDispatcher] in context with path [/brc] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.test.model.Protein.whOrthologs, no session or session was closed] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.test.model.Protein.whOrthologs, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)
at org.test.web.TestController.testSameWhOrthologSet(ViprGeneDetailController.java:742)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:139)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:232)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:232)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:232)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicatio
nFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
这是一个懒惰的例外。在返回对象之前,必须初始化日志
public Protein getProteinById(Long proteinId) {
Protein protein = (Protein) getSessionFactory().getCurrentSession().get(Protein.class, proteinId);
protein.getWhOrthologs();
return protein;
}
谢谢卡卡西!我们正在使用OpenSessionInViewFilter,它允许我们在后期检索延迟加载的PersistentSet。您的筛选器包括所有EndPoId。例如/*这个mach all endpointscorect,我们已经测试过它工作正常,除了加载在同一事务中共享同一组wherthologs的两个不同蛋白质记录时。如果我在加载secondProtein之前移动上面示例中的for循环,它就可以正常工作。但我不明白的是为什么for循环的顺序很重要。我认为在映射类中使用equals和hashcode,因为您的对象没有检测到差异
public Protein getProteinById(Long proteinId) {
Protein protein = (Protein) getSessionFactory().getCurrentSession().get(Protein.class, proteinId);
protein.getWhOrthologs();
return protein;
}