2012-01-19 3 views
7

DataAccessException 처리에 문제가 있습니다.Spring에서 DuplicateKeyException 대신 JpaSystemException을 발생했습니다.

고유 키 제약 조건을 위반하면 DuplicateKeyException이 아닌 JpaSystemException이 발생합니다!

이 문제에 관해 이야기하는 스레드가 있지만 문제를 해결하는 데 아무 도움이되지 않습니다. 어떻게하면 구체적인 org.springframework.dao 예외에 매핑 할 수 있습니까?

내 persistence.xml 파일에 다음과 같이 :

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
    <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider>   
     <class>...</class> 
     <class>...</class> 
     ... 
     <exclude-unlisted-classes /> 
     <properties> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/> 
      <property name="hibernate.hbm2ddl.auto" value="update"/> 
      <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/> 
      <property name="hibernate.connection.charSet" value="UTF-8"/> 
      <property name="hibernate.show.sql" value="true"/> 

      <property name="hibernate.ejb.event.post-insert" value="org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener" /> 
     <property name="hibernate.ejb.event.post-update" value="org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener" /> 
     <property name="hibernate.ejb.event.post-delete" value="org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener" /> 
     <property name="hibernate.ejb.event.pre-collection-update" value="org.hibernate.envers.event.AuditEventListener" /> 
      <property name="hibernate.ejb.event.pre-collection-remove" value="org.hibernate.envers.event.AuditEventListener" /> 
     <property name="hibernate.ejb.event.post-collection-recreate" value="org.hibernate.envers.event.AuditEventListener" /> 
    </properties>   
    </persistence-unit>  
    <persistence-unit name="persistenceUnitI24" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <class>...</class> 
     <class>...</class> 
     <exclude-unlisted-classes /> 
     <properties> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/> 
      <property name="hibernate.hbm2ddl.auto" value="validate"/> 
      <property name="hibernate.connection.charSet" value="UTF-8"/> 
      <property name="hibernate.showsql" value="true"/>   
     </properties> 
    </persistence-unit> 
</persistence> 

와 MySQL 트랜잭션 관리자에 대한 구성 : 그 관련이없는 나는 생각하기 때문에 내가 SQLSERVER에 대한 구성을 생략 한

<bean id="entityManagerFactory" 
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
      p:dataSource-ref="dataSource" 
      p:persistenceUnitName="persistenceUnit" 
      p:jpaProperties=""> 
      <property name="jpaVendorAdapter"> 
     <bean 
      class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
       <property name="showSql" value="true" /> 
       <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" /> 
       <property name="database" value="MYSQL"/>   
     </bean> 
     </property> 
      <property name="jpaDialect"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> 
      </property> 
    </bean> 

    <bean id="transactionManager" 
      class="org.springframework.orm.jpa.JpaTransactionManager" 
      p:entityManagerFactory-ref="entityManagerFactory"/> 

    <tx:annotation-driven transaction-manager="transactionManager" /> 

. 나는이 DB에 대한 번역 오류에 관심이 없다. 잡기

ERROR: org.hibernate.util.JDBCExceptionReporter - Duplicate entry 'A' for key 'code' 

: 내 로그에서 가져온

@Test(expected=DuplicateKeyException.class) 
public void createNewUbi(){ 
    Ubi ubi = new Ubi(); 
    ubi.setCode("A"); 
    ubiDao.save(ubi);  

    ubi = new Ubi(); 
    ubi.setCode("A"); 

    ubiDao.save(ubi);     
} 

: 다음과 같은 간단한 JUnit 테스트를 수행하려고

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> 

: 나는 또한 콩을 포함 시켰습니다

두 번째 저장 전화의 예외는 내가 가지고있는 것으로 나타났습니다 :

,
JpaSystemException: cause: javax.persistence.PersistenceException 
PersistenceException: cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException 

나는이 예외있어 웹 애플리케이션에서 삽입을하려고하는 경우 :

org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:311) 
    org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:15) 
    it.cpmapave.pm.dao.jpa.GenericDaoJpa.save(GenericDaoJpa.java:29) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    java.lang.reflect.Method.invoke(Method.java:597) 
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) 
    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.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
    $Proxy56.save(Unknown Source) 
    it.cpmapave.pm.service.amministrazione.SettoreServiceImpl.saveSettore(SettoreServiceImpl.java:34) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    java.lang.reflect.Method.invoke(Method.java:597) 
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) 
    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) 
    $Proxy57.saveSettore(Unknown Source) 
    it.cpmapave.pm.controller.amministrazione.SettoreController.create(SettoreController.java:42) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    java.lang.reflect.Method.invoke(Method.java:597) 
    org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) 
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436) 
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424) 
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790) 
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) 
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:669) 
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:585) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:641) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:113) 
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369) 
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) 
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168) 
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) 
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) 
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) 
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) 
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:84) 
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405) 
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:279) 
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515) 
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300) 
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    java.lang.Thread.run(Thread.java:662) 

내가 MySQL의 쿼리 로깅 설정 한을 나는 다음과 같은 쿼리를 가지고 : 나는 경우

insert into ubi (code, version) values ('A', 0) 

을 MySQL의 콘솔에서 쿼리를 실행하려고 : 나는 ERROR 1062 (23000): Duplicate entry 'A' for key 'code'

에서 검색에 sql-error-codes.xml에서 검색 때문에 잘못 특성에

<property name="duplicateKeyCodes"> 
    <value>1062</value> 
</property> 

그래서 나는 몇 가지 예외 번역에 문제가 있다고 생각합니다 ..하지만 어떤 : spring-jdbc-3.0.6.RELEASE.jar의 10 난 오류 코드 1,062데시벨 MySQL은이 방법으로 구성되어 있음을 발견?

나는 봄 3.0.6.RELEASE 및 최대 절전 모드 3.6.9.FINAL을 사용하고

는 답장을 보내 주셔서 감사합니다! 마르코

+0

@skaffman를 제공하기 시작, 그것은 UncategorizedDataAccessException의 하위 클래스 다음 DataAccessException과의. 제 경우 DuplicateKeyException 같은 분류 된 예외에 어떻게 맵핑 할 수 있는지 알고 있습니까? 고맙습니다! – gipinani

+0

@skaffman 추가 정보가있는 게시물을 업데이트했습니다. – gipinani

+0

maven에서 프로젝트를 컴파일 할 때 경고 메시지가 나타납니다. 경고 : org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect에 정의 된 조언이 적용되지 않았습니다. 원인이 될 수 있습니까? :) – gipinani

답변

3

이 문제는 Spring 또는 데이터베이스 드라이버와 관련이 없습니다. 나 자신을 잠시 뒤로 돌려 봐야했다. JPA 프로 바이더로서의 Hibernate를 사용할 수있게 해주는 hibernate-entitymanager jar에는 약간의 예외 변환이 있습니다.AbstractEntityManagerImpl.convert() 메서드는 HibernateException을 JPA PersistenceException으로 변환하지만 모든 종류의 "중복 키"또는 "고유 제한"예외는 전혀 처리하지 않습니다. latest code on Github조차도 그것을 수정하지 않은 것 같습니다. 살펴보면 convert() 메소드에는 긴 체인이 있지만 그 중 특정 예외를 포함하지 않으므로 맨 아래로 떨어지고 일반 PersistenceException으로 변환됩니다. 그것은 다소 성가신 일입니다.

4

EntityManagervendorAdapter이 설정되어 있는지 확인하십시오. 이렇게하면 jpa 제공 업체가 고급 오류 코드를 제공 할 수 있습니다.

1

설정이 내 것이 었습니다.

transactionManager.setJpaDialect(new HibernateJpaDialect()); 

내가 멀리 댓글을 달았 갑자기 내 응용 프로그램을 좋아 DuplicateKeyException에게