Только что начал проект, который имеет странный дизайн базы данных от предыдущих разработчиков. И я нашел исправление для решения проблемы. Но я хочу услышать от других, почему это происходит с OpenSessionInViewFilter настроен в web.xml и работает правильно на ленивых загруженных наборах, кроме этого случая. Ниже приведена модифицированная версия реального кода для объяснения сценария.Доступ к двум объектам имеет то же значение PersistentSet, что сеанс или сеанс не закрыты?
Единственное, что я могу придумать, это то, что оба белка в примере имеют одинаковую ссылку на тот же набор, который связан с номером 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;
}
}
WhOrtholog.java
@Entity
@Table(name = "WH_ORTHOLOG")
public class WhOrtholog implements java.io.Serializable {
private static final long serialVersionUID = 8633704022470442701L;
private Long id;
private Long score;
private String source;
private String strainName;
private String ncbiProteinGi;
@Id
@Column(name = "Ortholog_Id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "SCORE")
public Long getScore() {
return this.score;
}
public void setScore(Long score) {
this.score = score;
}
@Column(name = "SOURCE")
public String getSource() {
return this.source;
}
public void setSource(String source) {
this.source = source;
}
@Column(name = "STRAINNAME")
public String getStrainName() {
return this.strainName;
}
public void setStrainName(String strainName) {
this.strainName = strainName;
}
@Column(name = "NCBIPROTEINGI")
public String getNcbiProteinGi() {
return ncbiProteinGi;
}
public void setNcbiProteinGi(String ncbiProteinGi) {
this.ncbiProteinGi = ncbiProteinGi;
}
}
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);
}
LookupDao.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)
Thanks Kakashi! Мы используем OpenSessionInViewFilter, который позволяет нам получить ленивый загруженный PersistentSet на более позднем этапе. – shokulei
ваш фильтр включает в себя все endpoind. например/* url-pattern> this mach all endpoints –
Правильно, мы протестировали его работоспособно, за исключением случаев, когда загружаются две разные записи протеина, которые имеют одну и ту же совокупность WhOrthologs в той же транзакции. Если я перемещаю цикл for в примере выше до загрузки второгоProtein, он отлично работает. Но то, что я не могу понять, является причиной того, что порядок цикла for имеет значение. – shokulei