Java 访问共享同一PersistentSet的两个对象是否导致没有会话或会话已关闭?

Java 访问共享同一PersistentSet的两个对象是否导致没有会话或会话已关闭?,java,spring,hibernate,lazy-loading,Java,Spring,Hibernate,Lazy Loading,刚刚启动了一个项目,该项目具有以前开发人员提供的奇怪数据库设计。我已经找到了解决这个问题的方法。但是我想听听其他人为什么会这样,因为OpenSessionInViewFilter是在web.xml中配置的,并且可以在延迟加载集上正常工作,除了这种情况。下面是真实代码的修改版本,用于解释该场景 我能想到的唯一一件事是,在这个例子中,两种蛋白质对同一个集合有相同的引用,该集合与ncbiGI编号66275854相连。有没有人遇到过类似的问题并知道原因 Protein.java @Entity @Tab

刚刚启动了一个项目,该项目具有以前开发人员提供的奇怪数据库设计。我已经找到了解决这个问题的方法。但是我想听听其他人为什么会这样,因为OpenSessionInViewFilter是在web.xml中配置的,并且可以在延迟加载集上正常工作,除了这种情况。下面是真实代码的修改版本,用于解释该场景

我能想到的唯一一件事是,在这个例子中,两种蛋白质对同一个集合有相同的引用,该集合与ncbiGI编号66275854相连。有没有人遇到过类似的问题并知道原因

Protein.java

@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;
}