根本原因是
org.hibernate.TransactionException: Already have an associated managed connection
如果有人可以帮助我了解问题的原因。请随时询问更多详细信息。我可能想到的一个可能原因是,在该部分中,我正在获取此异常并执行@JoinColumn来联接两个表并显示结果。我应该采取什么预防措施来避免这种情况。
package com.next.domain; import static javax.persistence.GenerationType.AUTO; import static org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals; import static org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode; import static org.apache.commons.lang.builder.ToStringBuilder.reflectionToString; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; @Entity @Table(name="answers") @XmlRootElement public class Answer implements Serializable { private static final long serialVersionUID = 1L; private Long mId; private Long mQuizId; @Size(max=1000, message="\'Description\' must be less than 1000 characters.") private String mContent; private Date mRegDate; @Id @GeneratedValue(strategy = AUTO) public Long getId() { return mId; } public void setId(Long id) { mId = id; } @Column(name="quiz_id") public Long getQuizId() { return mQuizId; } public void setQuizId(Long quizId) { mQuizId = quizId; } @Column(name="content") public String getContent() { return mContent; } public void setContent(String content) { mContent = content; } @Column(name="reg_date") public Date getRegDate() { return mRegDate; } public void setRegDate(Date regDate) { mRegDate = regDate; } @Override public boolean equals(Object obj) { return reflectionEquals(this, obj); } @Override public int hashCode() { return reflectionHashCode(this); } @Override public String toString() { return reflectionToString(this); } } package com.next.domain; import static javax.persistence.GenerationType.AUTO; import static org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals; import static org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode; import static org.apache.commons.lang.builder.ToStringBuilder.reflectionToString; import java.io.Serializable; import java.util.Date; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; import org.hibernate.validator.constraints.NotEmpty; @Entity @Table(name="quizzes") @XmlRootElement public class Quiz implements Serializable { private static final long serialVersionUID = 1L; private Long mId; private Integer mSection; private Long mAnswerId; @NotEmpty(message="\'Title\' must not be empty.") @Size(max=64, message="\'Title\' must be less than 64 characters.") private String mTitle; @Size(max=256, message="\'Question\' must be less than 256 characters.") private String mContent; @Size(max=256, message="\'Description\' must be less than 256 characters.") private String mDescription; private List<Answer> mAnswers; private Date mRegDate; @Id @GeneratedValue(strategy = AUTO) public Long getId() { return mId; } public void setId(Long id) { mId = id; } @Column(name="section") public Integer getSection() { return mSection; } public void setSection(Integer mSection) { this.mSection = mSection; } @Column(name="answer_id") public Long getAnswerId() { return mAnswerId; } public void setAnswerId(Long answer_id) { mAnswerId = answer_id; } @Column(name="title") public String getTitle() { return mTitle; } public void setTitle(String title) { mTitle = title; } @Column(name="content") public String getContent() { return mContent; } public void setContent(String content) { mContent = content; } @Column(name="description") public String getDescription() { return mDescription; } public void setDescription(String description) { mDescription = description; } @OneToMany(cascade={CascadeType.MERGE, CascadeType.REMOVE}) @JoinColumn(name="quiz_id", referencedColumnName="id") public List<Answer> getAnswers() { return mAnswers; } public void setAnswers(List<Answer> answers) { mAnswers = answers; } @Column(name="reg_date") public Date getRegDate() { return mRegDate; } public void setRegDate(Date regDate) { mRegDate = regDate; } @Override public boolean equals(Object obj) { return reflectionEquals(this, obj); } @Override public int hashCode() { return reflectionHashCode(this); } @Override public String toString() { return reflectionToString(this); } } package com.next.persistence; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.next.domain.Answer; import com.next.domain.Quiz; import com.next.domain.QuizSubmission; @Repository("quizDao") @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class) public class QuizDaoImpl implements QuizDao { private static final String QUIZ_SELECT_CLAUSE = "select new map(q.id as id, q.title as title, q.regDate as regDate)"; private static final String ANSWER_SELECT_CLAUSE = "select new map(a.id as id, a.content as content)"; @PersistenceContext(type=PersistenceContextType.EXTENDED) private EntityManager em; @Override public void addQuiz(Quiz quiz) { em.persist(quiz); } @Override public void saveQuiz(Quiz quiz) { em.merge(quiz); } @Override public void deleteQuiz(long id) { try { em.remove(getQuiz(id)); } catch (IllegalArgumentException ie) { return; } } @Override public Quiz getQuiz(long id) { Quiz quiz = null; try { quiz = em.find(Quiz.class, id); } catch (NoResultException e) {} return quiz; } @Override public void addAnswer(Answer answer) { em.persist(answer); } @Override public void saveAnswer(Answer answer) { em.merge(answer); } @Override public void deleteAnswer(long id) { try { em.remove(getAnswer(id)); } catch (IllegalArgumentException ie) { return; } } @Override public Answer getAnswer(long id) { Answer answer = null; try { answer = em.find(Answer.class, id); } catch (NoResultException e) {} return answer; } @SuppressWarnings("unchecked") @Override public List<Map<String, Object>> getAnswers(long quizId) { return (List<Map<String, Object>>) em.createQuery(ANSWER_SELECT_CLAUSE + " from Answer a where a.quizId = :quizId") .setParameter("quizId", quizId) .getResultList(); } @SuppressWarnings("unchecked") @Override public List<Map<String, Object>> getQuizzes(int section) { return (List<Map<String, Object>>) em.createQuery(QUIZ_SELECT_CLAUSE + " from Quiz q where q.section = :section order by q.regDate desc") .setParameter("section", section) .getResultList(); } @SuppressWarnings("unchecked") @Override public List<Map<String, Object>> getQuizzesDetails(int section) { return (List<Map<String, Object>>) em.createQuery("select q from Quiz q where q.section = :section order by q.regDate desc") .setParameter("section", section) .getResultList(); } @Override public Answer getAnswerByQuizId(long quizId) { Answer answer = null; try { answer = em.find(Answer.class, quizId); } catch (NoResultException e) { } return answer; } @Override public void addQuizSubmission(QuizSubmission quizSubmission) { em.persist(quizSubmission); } @Override public void saveQuizSubmission(QuizSubmission quizSubmission) { em.merge(quizSubmission); } @Override public void deleteQuizSubmission(long id) { try { em.remove(getQuiz(id)); } catch (IllegalArgumentException ie) { return; } } @Override public QuizSubmission getQuizSubmission(long id) { QuizSubmission quizSubmission = null; try { quizSubmission = em.find(QuizSubmission.class, id); } catch (NoResultException e) {} return quizSubmission; } @SuppressWarnings("unchecked") @Override public List<Map<String, Object>> getQuizSubmissions(long quizId) { return (List<Map<String, Object>>) em.createQuery("select qs from QuizSubmission qs where qs.quizId = :quizId order by qs.date desc") .setParameter("quizId", quizId) .getResultList(); } @SuppressWarnings("unchecked") @Override public List<QuizSubmission> getQuizSubmissions(String date) { /*return em.createNativeQuery("SELECT `id`, `quiz_id`, `answer_id`, `date` FROM `quizzes_submissions` WHERE DATE(`date`) = :date") .setParameter("date", date ) .getResultList();*/ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date startDate = null; Date endDate = null; try { startDate = format.parse(date.trim()+" 00:00:00"); endDate = format.parse(date.trim()+" 23:59:59"); } catch (ParseException e) { e.printStackTrace(); } return em.createQuery("select qs from QuizSubmission qs WHERE qs.date BETWEEN :startDate AND :endDate") .setParameter("startDate", startDate) .setParameter("endDate", endDate) .getResultList(); } }
我的控制器调用QuizDaoImpl的getQuizzes(int部分),以便可以显示所有测验。
我的观察: 完全可以在新部署下正常运行,一旦数据库很长时间就理想了,则问题会在6-8小时后发生
root cause org.hibernate.TransactionException: Already have an associated managed connection org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:65) org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160) org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1309) org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:57) org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.enlistInCurrentTransaction(ExtendedEntityManagerCreator.java:421) org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.doJoinTransaction(ExtendedEntityManagerCreator.java:398) org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:356) sun.proxy.$Proxy150.createQuery(Unknown Source) com.next.persistence.QuizDaoImpl.getQuizzes(QuizDaoImpl.java:102) sun.reflect.GeneratedMethodAccessor358.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:601) org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318) org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) sun.proxy.$Proxy163.getQuizzes(Unknown Source) com.next.service.QuizServiceImpl.getQuizzes(QuizServiceImpl.java:92) sun.reflect.GeneratedMethodAccessor357.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:601) org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318) org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) sun.proxy.$Proxy164.getQuizzes(Unknown Source) com.next.mvc.HomeController.showListPage(HomeController.java:308) sun.reflect.GeneratedMethodAccessor356.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:601) org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213) org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) javax.servlet.http.HttpServlet.service(HttpServlet.java:617) javax.servlet.http.HttpServlet.service(HttpServlet.java:717) org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311) org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116) org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173) org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
问题出在@PersistenceContext批注中。我有:
@PersistenceContext(type = PersistenceContextType.EXTENDED) private EntityManager entityManager;
我将其替换为:
@PersistenceContext private EntityManager entityManager;