JPA Transaction不在方法结束时提交

时间:2016-05-04 14:40:17

标签: spring hibernate commit flush transactional

我有两种方法:

1:
@Transactional
public Long add(Long clientId) {
    Contact contact = new Contact();
    contact.setClientId(clientId);
    contact.setValue('test@test.com');
    contact.setType('EMAIL');
    contact.setDateStart(new Date());
    // autowired repo
    return contactRepository.saveAndFlush(contact);
}

2:
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void emailsValidator(Long clientId) {
    Specification<Client> spec = ClientSearchSpecification.getByClientIdWithActiveEmails(clientId);
    List<Client> clientList = clientRepository.findAll(spec);
}

SearchSpecification:
 public static Specification<Client> getByClientIdWithActiveEmails(Long clientId) {
    return (root, query, cb) -> {
        query.distinct(true);
        Join<Client, Contact> clientContactJoin = (Join) root.fetch(Client_.contactList);
        List<Predicate> predicates = new ArrayList<>();
        predicates.add(cb.equal(root.get(AbstractEntity_.id), clientId));
        predicates.add(cb.equal(clientContaktJoin.get(Contakt_.type), 'EMAIL'));
        predicates.add(cb.lessThan(clientContaktJoin.get(Contakt_.dateStart), cb.currentTimestamp()));
        return cb.and(predicates.toArray(new Predicate[predicates.size()]));
    };
}

主要方法:

@RequestMapping(value = "/{clientId}/contact/add", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public void addContact(@PathVariable(value = "clientId") Long clientId) {
    contactService.add(clientId);
    errorValidationService.emailsValidator(clientId);
}

我的数据库属性:

hibernate.transaction.auto_close_session: true
hibernate.connection.autocommit: true
org.hibernate.flushMode: COMMIT

问题 - 在执行步骤2时,DB不包含步骤1中的新实体。该对象仅在所有其余调用完成后提交。如何在步骤1中提交实体,以便我可以在步骤2中选择并加入实体?

2 个答案:

答案 0 :(得分:0)

您无需承诺选择您的数据(在同一交易中)。

这里的问题是你说第2步需要是'NOT_SUPPORTED,这意味着第1步必须在步骤2之前提交它才能看到它插入的任何数据。

尝试将步骤1的传播更改为REQUIRES_NEW,以确保在进入第2步之前进行提交。

答案 1 :(得分:0)

事实证明我在存储库界面中使用了两种不同的@Transaction实现:

@Transactional
public interface ClientRepository extends JpaRepository<Client, Long>, JpaSpecificationExecutor<Client>

我用过:

import javax.transaction.Transactional;

我应该使用:

import org.springframework.transaction.annotation.Transactional;

这意味着没有应用spring @Transaction的设置,并且它无法在方法结束时提交,它只在调用结束时提交。