2015-06-05 25 views
6

Sto cercando di ottenere un migliore controllo sull'utilizzo dell'attributo @Transactional di Spring. Capisco che fondamentalmente avvolge il contenuto del metodo contrassegnato come @Transactional in una transazione. Sarebbe opportuno contrassegnare un metodo di servizio/livello aziendale come transazionale, in contrasto con il metodo DAO effettivo, come ho fatto qui?Annotazione transazionale a molla

Servizio Attuazione

public class UserServiceImpl implements UserServiceInt{ 
    @Autowired 
    private UserServiceDAO serviceDAO; 


    @Override 
    public User getUser(int id){ 
     return serviceDAO.getUser(id); 
    } 

    @Override 
    @Transactional 
    public void updateUserFirstName(int id, String firstName) throws SomeException{ 
     User userToUpdate = getUser(id); 
     if(userToUpdate == null){ 
     throw new SomeException("User does not exist"); 
     } 
     userToUpdate.setFirstName(firstName); 
     serviceDAO.updateUser(userToUpdate); 
    } 

} 

DAO Attuazione

public class UserServiceDAOImpl implements UserServiceDAOInt{ 
    @PersistenceContext(unitName="myUnit") 
    private EntityManager entityManager; 

    @Override 
    public void updateUser(User user){ 
     entityManager.merge(user); 
    } 

} 

io non sono nemmeno sicuro se la chiamata di unire è nemmeno necessario. In che modo Spring sa quale EntityManager utilizzare poiché non esiste un dichiarante EntityManager nella classe UserServiceImpl?

+0

Sì, è proprio il caso di annotare un servizio o di servizi metodi come '@ Transactional' - ad esempio in caso il servizio comprende più di un DAO singolo. Inoltre, hai ragione, non devi chiamare esplicitamente fusione. L'oggetto User è già associato al contesto di persistenza (chiamando 'get()') e lo stato è sincronizzato con il DB alla fine della transazione. Unisci viene utilizzato per aggiornare un oggetto che è stato modificato al di fuori di una transazione –

+0

un po 'di argomento per la tua domanda, ma potresti trovare pertinente, dai un'occhiata a http://projects.spring.io/spring-data-jpa/rimuoverà un sacco di codice boilerplate dal tuo livello DAO – Kajo

+0

Controlla la mia risposta qui, forse ti sarà di aiuto http://stackoverflow.com/questions/30490924/what-data-is-stored-in-transaction/30494434# 30494434 – jgr

risposta

2

Contrassegniamo un livello di servizio con @Transactional quando un metodo in una classe di servizio ha più chiamate di database e vogliamo che tutte o tutte le chiamate si verifichino o che nessuno debba accadere o possiamo dire che se una chiamata fallisce, l'intera transazione deve essere rollback. Se non rientriamo in questo criterio, possiamo anche optare per lo @Transactional sul livello DAO.

In che modo Spring sa quale EntityManager utilizzare poiché non esiste un EntityManager dichiarato nella classe UserServiceImpl?

primavera si riferisce l'EntityManager da persistence.xml (da classpath), la cui struttura è simile a quella di seguito:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> 
    <persistence-unit name="myUnit"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <jta-data-source>java:/YourDatasource</jta-data-source> 

     <properties> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> 
      <property name="hibernate.hbm2ddl.auto" value="update" /> 
      <property name="hibernate.show_sql" value="true" /> 
     </properties> 
    </persistence-unit> 
</persistence> 
Problemi correlati