2012-01-02 53 views
0

我需要原子堅持在數據庫中的一些實體,但我有一些困難...... 我有4個實體:Emitente,NotaFiscal,項目和Duplicata。 實體項目和Duplicata取決於NotaFiscal取決於Emitente。 所以,我的DAO類嘗試堅持Emitente然後NotaFiscal然後Duplicata終於項目。 但是,當我試圖堅持NotaFiscal我收到一個錯誤,指出Emitente不存在。 這些相同的實體被正確地持續使用entityManager.getTransaction()()開始。方法時,這個程序是一個桌面...如何使Spring的事務原子

這是所有調用DAO類的類:

public class ControladorArmazenamentoNFeCompleta extends BaseDao implements 
    IControladorArmazenamentoNotaFiscalCompleta { 

private static final long serialVersionUID = 1L; 
private IControladorArmazenamentoNFe armazenadorNFe; 
private IControladorArmazenamentoElementoNFe<Item> armazenadorItem; 
private IControladorArmazenamentoEmitente armazenadorEmitente; 
private IControladorArmazenamentoElementoNFe<Duplicata> armazenadorDuplicata; 
private String mensagemErro; 

public ControladorArmazenamentoNFeCompleta(
     EntityManagerFactory entityManagerFactory) { 
    super(entityManagerFactory); 
} 

public StatusArmazenamento criar(NotaFiscal bean) { 
    if (armazenarEmitente(bean)) { 
      if (armazenadorNFe.recuperarPelaChave(bean.getId()) == null) { 
       if (armazenadorNFe.criar(bean)) { 
        if (armazenarDuplicatas(bean)) { 
         if (armazenarItens(bean)) {        
          return StatusArmazenamento.SUCESSO; 
         } else { 
          mensagemErro = armazenadorItem 
            .getMensagemErro(); 
         } 
        } else { 
         mensagemErro = armazenadorDuplicata 
           .getMensagemErro(); 
        } 
       } else { 
        mensagemErro = armazenadorNFe.getMensagemErro(); 
       } 
      } else { 
       mensagemErro = "A nota fiscal já foi importada!"; 
       return StatusArmazenamento.IMPORTADA_ANTERIORMENTE; 
      } 
     } 
    return StatusArmazenamento.ERRO; 
} 

private boolean armazenarEmitente(NotaFiscal bean) { 
    if (armazenadorEmitente.recuperarPeloId(bean.getEmitente() 
      .getNumeroCadastroNacional()) == null) { 
     if (!armazenadorEmitente.criar(bean.getEmitente())) { 
      mensagemErro = armazenadorEmitente.getMensagemErro(); 
      return false; 
     } 
    } 
    return true; 
} 

private boolean armazenarDuplicatas(NotaFiscal notaFiscal) { 
    armazenadorDuplicata.setChaveNotaFiscal(notaFiscal.getId()); 
    Cobranca cobranca = notaFiscal.getCobranca(); 
    if (cobranca != null) { 
     for (Duplicata duplicata : cobranca.getListaDeDuplicatas()) { 
      if (!armazenadorDuplicata.criar(duplicata)) 
       return false; 
     } 
    } 
    return true; 
} 

private boolean armazenarItens(NotaFiscal notaFiscal) { 
    armazenadorItem.setChaveNotaFiscal(notaFiscal.getId()); 
    if (notaFiscal.getListaDeItens() == null) 
     return false; 
    for (Item item : notaFiscal.getListaDeItens()) { 
     if (!armazenadorItem.criar(item)) 
      return false; 
    } 
    return true; 
} 

,這是彈簧的配置:

<bean id="transactionManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager" /> 

<tx:advice id="txDao"> 
    <tx:attributes> 
     <tx:method name="recuperar*" read-only="true" /> 
     <tx:method name="criar" rollback-for="PreexistingEntityException,Exception"/> 
     <tx:method name="editar" 
      rollback-for="IllegalOrphanException,NonexistentEntityException,Exception"/> 
    </tx:attributes> 
</tx:advice> 

<tx:advice id="txControlador"> 
    <tx:attributes> 
     <tx:method name="criar" rollback-for="Exception"/> 
     <tx:method name="atualizar" rollback-for="Exception"/> 
    </tx:attributes> 
</tx:advice> 

<aop:config> 
    <aop:pointcut id="operacoesDao" 
     expression="execution(* com.hrgi.persistencia.dao.*.*(..))" /> 
    <aop:pointcut id="operacoesCadastroDao" 
     expression="execution(* com.hrgi.persistencia.cadastro.dao.interfaces.*.*(..))" /> 
    <aop:pointcut id="operacoesBancoDao" 
     expression="execution(* com.hrgi.persistencia.banco.dao.interfaces.*.*(..))" /> 
    <aop:pointcut id="operacoesNFeDao" 
     expression="execution(* com.hrgi.persistencia.nfe.dao.interfaces.*.*(..))" /> 
    <aop:pointcut id="operacoesControladorArmazenamento" 
     expression="execution(* com.hrgi.persistencia.*.*(..))" /> 
    <aop:pointcut id="operacoesControladorArmazenamentoNFe" 
     expression="execution(* com.hrgi.persistencia.nfe.controladores.interfaces.*.*(..))" /> 

    <aop:advisor advice-ref="txDao" pointcut-ref="operacoesDao" /> 
    <aop:advisor advice-ref="txDao" pointcut-ref="operacoesCadastroDao" /> 
    <aop:advisor advice-ref="txDao" pointcut-ref="operacoesBancoDao" /> 
    <aop:advisor advice-ref="txDao" pointcut-ref="operacoesNFeDao" /> 
    <aop:advisor advice-ref="txControlador" 
     pointcut-ref="operacoesControladorArmazenamento" /> 
    <aop:advisor advice-ref="txControlador" 
     pointcut-ref="operacoesControladorArmazenamentoNFe" /> 
</aop:config> 

我能做什麼來解決這個問題??

+0

嘗試重新實現它的英文,因爲這是很難理解,因爲它是。它應該是JPA代碼,但沒有任何實體管理器的調用,所以我們甚至不知道所有這些方法做什麼。 – 2012-01-02 22:38:31

回答

0

我解決簡單地改變傳播的問題:

<tx:advice id="txDao"> 
    <tx:attributes> 
     <tx:method name="recuperar*" read-only="true" /> 
     <tx:method name="criar" rollback-for="PreexistingEntityException,Exception" 
      propagation="REQUIRED" /> 
     <tx:method name="editar" 
      rollback-for="IllegalOrphanException,NonexistentEntityException,Exception" 
      propagation="REQUIRED" /> 
    </tx:attributes> 
</tx:advice> 

<tx:advice id="txControlador"> 
    <tx:attributes> 
     <tx:method name="criar" rollback-for="Exception" 
      propagation="REQUIRES_NEW" /> 
     <tx:method name="atualizar" rollback-for="Exception" 
      propagation="REQUIRES_NEW" /> 
    </tx:attributes> 
</tx:advice> 

感謝您的關注。