使用JPA,Spring orm,Hibernate延迟插入

时间:2014-06-04 15:56:42

标签: hibernate jpa spring-orm

好吧,这是一个非常奇怪的行为与已经提到的技术,我有一个调用服务的控制器,这调用一个dao传递给持久的实体有一个带注释@Column nullable = false, unique = true的字段,当我运行dao或服务的测试,并插入重复的值,抛出异常 org.springframework.dao.DataIntegrityViolationException这是好的,是预期的行为。但是当我运行Web应用程序时,在服务完成后抛出异常,执行dao时执行no。所以这迫使我在控制器中捕获异常,而不是在服务中。

  1. controller // start
  2. 服务//继续
  3. DAO //继续(但此时应该抛出异常)
  4. service //完成(try try围绕dao,但没有抛出异常)。
  5. 控制器//抛出异常。
  6. 我在每种方法中添加了一些日志,所以我可以看到

      

    插入...

    服务调用结束后执行

    句子。

    谢谢。

    修改

    这是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;。

2 个答案:

答案 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;
}