好吧,这是一个非常奇怪的行为与已经提到的技术,我有一个调用服务的控制器,这调用一个dao传递给持久的实体有一个带注释@Column nullable = false, unique = true
的字段,当我运行dao或服务的测试,并插入重复的值,抛出异常
org.springframework.dao.DataIntegrityViolationException
这是好的,是预期的行为。但是当我运行Web应用程序时,在服务完成后抛出异常,执行dao时执行no。所以这迫使我在控制器中捕获异常,而不是在服务中。
我在每种方法中添加了一些日志,所以我可以看到
服务调用结束后执行插入...
句子。
谢谢。
修改
这是xml事务定义。
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="crea*" propagation="REQUIRED"/>
<tx:method name="obtener*" propagation="SUPPORTS" read-only="true" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.company.service..*.*(..))"
id="txPointcut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
</aop:config>
这是2段代码,第一段是捕获异常。
package com.company.service.tarea.ventas.impl
public Producto obtenerSiExisteDuplicadaClave(String clave) {
try{
return productoService.buscarPorClave(clave);
}catch(EmptyResultDataAccessException e){
log.error(e.getMensaje());
}
return null;
}
此代码无效
com.company.service.tarea.almacenpt.impl
public void creaEntradaProduccion(Entrada entrada, BindingResult bindingResult) {
if(log.isDebugEnabled())log.debug("creaEntradaProduccion");
entradaService.peristeEntrada(entrada);
if(log.isDebugEnabled())log.debug("persistido...");
}
抛出异常直到代码执行并将执行返回给控制器,它到达日志&#34; persistido&#34;。
答案 0 :(得分:1)
这是预料之中的。持久化实体仅将其与持久性上下文相关联。执行insert语句时将抛出异常,并且在刷新持久性上下文时执行该语句(这将在执行查询之前或提交事务之前自动发生)。
您的测试可能有效,因为测试中的事务是在进行DAO调用时启动的,并且在之后立即提交。而在生产中,DAO调用是作为现有事务的一部分进行的,在调用服务时启动,并在服务方法返回时提交。
答案 1 :(得分:1)
@OJVM:您正在捕获特定的异常(EmptyResultDataAccessException)。这是逃避try / catch块的相同例外。 要识别相同的内容,请放置一个通用的Exception块。记录下来。 一旦确定了逃避此块的特定异常,请在此处添加。
例如:
package com.company.service.tarea.ventas.impl
public Producto obtenerSiExisteDuplicadaClave(String clave) {
try{
return productoService.buscarPorClave(clave);
}catch(EmptyResultDataAccessException e){
log.error(e.getMensaje());
}catch(Exception e){
log.error(e.getMensaje()); // e.getMessage() ; // Once caught put handle this exception also specifically
}
return null;
}