2017-04-05 122 views
0

我有一個春天啓動(JPA /休眠)與javax.validation驗證註釋應用程序,當我在實體上執行交易我接受這些神祕的例外:如何更多詳細信息添加到JPA驗證異常

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction 
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656) 
    at com.voverc.eventmanager.eventservice.service.event.EventServiceImpl$$EnhancerBySpringCGLIB$$ea57e22c.archiveEvents(<generated>) 
    at sun.reflect.GeneratedMethodAccessor435.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) 
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) 
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: javax.persistence.RollbackException: Error while committing the transaction 
    at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:87) 
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) 
    ... 23 common frames omitted 
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.voverc.eventmanager.eventservice.domain.PhoneCall] during update time for groups [javax.validation.groups.Default, ] 
List of constraint violations:[ 
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=originatorNumber, rootBeanClass=class com.voverc.eventmanager.eventservice.domain.PhoneCall, messageTemplate='{org.hibernate.validator.constraints.NotBlank.message}'} 
    ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=direction, rootBeanClass=class com.voverc.eventmanager.eventservice.domain.PhoneCall, messageTemplate='{javax.validation.constraints.NotNull.message}'} 
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=originatorName, rootBeanClass=class com.voverc.eventmanager.eventservice.domain.PhoneCall, messageTemplate='{org.hibernate.validator.constraints.NotBlank.message}'} 
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=destinationName, rootBeanClass=class com.voverc.eventmanager.eventservice.domain.PhoneCall, messageTemplate='{org.hibernate.validator.constraints.NotBlank.message}'} 
] 
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138) 
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(BeanValidationEventListener.java:86) 
    at org.hibernate.action.internal.EntityUpdateAction.preUpdate(EntityUpdateAction.java:244) 
    at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:118) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) 
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) 
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282) 
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465) 
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963) 
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339) 
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231) 
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65) 
    at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61) 
    ... 24 common frames omitted 

是否有如何自定義這種異常(通過Spring或Hibernate),例如添加對象的標識符?我怎麼知道驗證失敗的對象是哪種(想象一下數百個元素的更新)?

+0

這是什麼使用JPA API。它是bean驗證API(這些註釋來自哪裏) –

+0

但是'BeanValidationEventListener'負責調用驗證並拋出異常。有沒有辦法用其他數據來定製它? –

+0

如果提供的內容不符合您的需求,爲什麼不寫下自定義事件偵聽器? – matthias

回答

0

可以在Bean驗證註解設置驗證消息:

@Column(name = "name") 
@NotNull(message = "{name.NotNull.message}") 
@Size(min = 3, max = 9999, message = "{name.Size.message}") 
private String name; 

設置郵件,你在你的資源,你存儲錯誤語句,如創建ValidationMessages.properties

name.NotNull.message=Name should not be null 
+0

我不想在錯誤的領域的更多細節。相反,我想知道哪個對象是錯誤的(例如,打印它的標識符) –

+0

@AlessandroDionisi你可以在消息中得到驗證的屬性,例如'name.Size.message = Name'$ {validatedValue}'是無效的,它應該介於{min}和{max}個字符' 如果這還不夠,您應該編寫自定義的ConstraintValidator,它可以讓您訪問整個bean對象 –