Spring JpaTransactionManager

时间:2016-09-26 21:41:11

标签: java spring jpa

我正在研究一个由队友开发的项目,但我们正面临一个让我发疯的奇怪问题:数据库永远不会更新,日志也不例外。这是代码:

@Service
@Transactional
public class InterventionProjectResultIntegrator implements IInterventionProjectResultIntegrator {

  private static final ILogger logger = ComponentLogger.getInstance(InterventionProjectResultIntegrator.class);

  private Dao dao;
  private String APPLICATION = "APP";

  @Autowired
  public void setDao(Dao dao){
    this.dao = dao; 
  }

  @Override
  public void integrateResponse() {

    try {
      List<ResponseEntity> responseListByStatus = dao.findAllResponseByStatus(Dao.STATUS_EN_COURS, APPLICATION);

      for (ResponseEntity response: responseListByStatus ) {
        response.setStatus(Dao.STATUS_OK);
        dao.mergeResponseEntity(response);
      }
    } catch (Exception ex) {
      logger.error(ex.getMessage(), ex);
      throw ex;
    }
  }
}

正如您所看到的,该功能非常简单:

  1. 从数据库中获取对象
  2. 循环对象
  3. 更新每个对象状态
  4. 在循环结束时提交更改
  5. 除了没有在数据库上更新对象并且没有例外之外,一切运行正常。

    Dao来自maven依赖,在另一个项目中工作正常,所以我认为这个问题与新问题有关。

    我可以在控制台中看到以下日志:

    org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@6dcee890] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@713e49c3] bound to thread org.hibernate.event.internal.AbstractSaveEventListener - Persistent instance of: com.domain.ResponseEntity
    org.hibernate.event.internal.DefaultMergeEventListener - Ignoring persistent instance
    org.hibernate.action.internal.UnresolvedEntityInsertActions - No entity insert actions have non-nullable, transient entity dependencies.
    

    您是否已经面临类似问题?

    问候。

    [编辑1]

    正如评论中指出的那样,我用 @Transactional 注释取代了手动事务处理。请参阅更新的代码。

    所以现在我在日志中有了一个新行,但结果相同,对象没有保存在数据库中。

    org.springframework.transaction.interceptor.TransactionAspectSupport - Completing transaction for [com.response.InterventionProjectResultIntegrator.integrateResponse]
    

    正如DAO来源所说。这段代码不在我的责任范围内,在另一种情况下就像魅力一样。

    @Repository
    public class Dao {
      public static final ILogger logger = ComponentLogger.getInstance(Dao.class);
    
      public static final String STATUS_EN_COURS = "PENDING";
      public static final String STATUS_OK = "OK";
      public static final String STATUS_ERROR = "ERROR";
    
      @PersistenceContext
      protected EntityManager entityManager;
    
      public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
      }
    
      public void mergeMvzResponseEntity(ResponseEntity responseEntity) {
        if(entityManager != null) {
          this.entityManager.merge(responseEntity);
        } else {
          logger.error("Entity manager not initialized");
        }
    }
    

1 个答案:

答案 0 :(得分:0)

正如所建议的那样,我重写了源代码以使用@Transactional注释,并让Spring处理事务:

@Service
@Transactional
public class InterventionProjectResultIntegrator implements IInterventionProjectResultIntegrator {

  private static final ILogger logger = ComponentLogger.getInstance(InterventionProjectResultIntegrator.class);

  private Dao dao;
  private String APPLICATION = "APP";

  @Autowired
  public void setDao(Dao dao){
    this.dao = dao; 
  }

  @Override
  public void integrateResponse() {

    try {
      List<ResponseEntity> responseListByStatus = dao.findAllResponseByStatus(Dao.STATUS_EN_COURS, APPLICATION);

      for (ResponseEntity response: responseListByStatus ) {
        response.setStatus(Dao.STATUS_OK);
        dao.mergeResponseEntity(response);
      }
    } catch (Exception ex) {
      logger.error(ex.getMessage(), ex);
      throw ex;
    }
  }
}

然后将此行添加到我的xml配置文件中:

<tx:annotation-driven/>

现在它就像一个魅力。感谢@M。 Deinum指出了它。