2016-05-04 18 views
1

Ich habe zwei Methoden:JPA Transaktion nicht am Ende des Verfahrens commiting

1: 
@Transactional 
public Long add(Long clientId) { 
    Contact contact = new Contact(); 
    contact.setClientId(clientId); 
    contact.setValue('[email protected]'); 
    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()])); 
    }; 
} 

Main-Methode:

@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); 
} 

Meine db Eigenschaften:

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

Das Problem - DB doesn Wenn Sie Schritt 2 ausführen, enthält das Objekt keine neue Entität aus Schritt 1. Das Objekt wird erst nach Abschluss aller restlichen Aufrufe übergeben. Wie verpflichte ich die Entität in Schritt 1, sodass ich sie in Schritt 2 auswählen und ihr beitreten kann?

+1

Konnten Sie den Code bekannt geben, der die zwei Methoden aufruft? –

Antwort

0

Sie müssen nicht verpflichtet sein, Ihre Daten auszuwählen (innerhalb derselben Transaktion).

Das Problem hier ist, dass Sie gesagt haben, Schritt 2 muss "NOT_SUPPORTED" sein, was bedeutet, dass Schritt 1 festgeschrieben werden muss, bevor Schritt 2 die eingegebenen Daten sehen kann.

Versuchen Sie, die Ausbreitung von Schritt 1-REQUIRES_NEW Ändern der Commit, um sicherzustellen, auftritt, bevor Sie zu Schritt erhalten 2.

+0

Bereits versucht, dass. Ja, ich kann die gesamte Auflistung von beanList mit geladenen Entitäten von Schritt 1 bekommen. Aber ich brauche nicht alle Entitätssammlungen, deshalb habe ich meine eigenen Suchkriterien, zB: where cr_date> current_timestamp und type = 'something'. Wenn ich eine der @Transactions auf die zweite Methode setze, ignoriert Hibernate meine gefilterten Suchkriterien und gibt alle mit dieser ID verknüpften Daten zurück. – user6291275

+0

Können Sie weitere Informationen darüber geben, wie Sie diese beiden Methoden aufrufen? Sind sie auf demselben Objekt? Welche @Transactional Annotation haben Sie beim Aufrufer dieser Methoden? Wenn möglich, poste mehr Code. –

+0

Vielen Dank für die schnelle Antwort, ich habe den Code aktualisiert. – user6291275

0

Es stellte sich heraus, dass ich mit zwei verschiedenen @Transaction Implementierungen in Repository-Schnittstelle:

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

I verwendet:

import javax.transaction.Transactional; 

sollte ich habe Nutzung:

import org.springframework.transaction.annotation.Transactional; 

Das bedeutete, dass Einstellungen für spring @Transaction nicht angewendet wurden und es sich am Ende der Methode nicht festlegen konnte, es wurde nur am Ende des Aufrufs festgelegt.