2015-11-30 17 views
7

ho hava due jdbi dao come questi:Utilizzando @Transaction in applicazione JDBI/Dropwizard

public interface dao1 { 
    @Query("insert into table1 ...") 
    findByid(myBean1); 
} 

public interface dao2 { 
    @Query("insert into table2 ...) 
    save(myBean2; 
    } 
} 

voglio eseguire salvataggio di due dao in una transazione come:

dao1.save(); 
dao2.save(); 

Con la primavera ho usato annotazione @ transazionale. Cosa posso fare con dropwizard e jdbi?

risposta

10

È possibile utilizzare @Transaction in JDBI. Ho scritto il blog qui. http://manikandan-k.github.io/2015/05/10/Transactions_in_jdbi.html

+0

Ciao, grazie questo è ciò di cui ho bisogno, ma come posso testare la classe che implementa l'interfaccia GetHandle? O se è necessario utilizzare diversi oggetti repository nella stessa transazione? – LucaA

+0

Non possiamo utilizzare due diversi repository nella stessa transazione. Se vuoi usare due Dao diversi, crea un repository contenente quei due Dao. Per testare la classe, qual è la difficoltà che stai affrontando? – Manikandan

+0

non possiamo prendere in giro daos nel test unitario del repository, perché sono iniettati dall'annotazione jdbi @SqlCreateObject e dal metodo jdbi.onDemand. È vero? – LucaA

-3

Uso @UnitOfWork

Esempio:

@POST 
@UnitOfWork 
public Role create(@Valid RoleApi roleApi) { 
    return roleService.create(roleApi); 
} 
+1

@UnitOfWork annotazione è attiva solo con fascio di ibernazione e non con uno jdbi. – LucaA

1

Secondo la documentazione jdbi,

aggiornamento, inserimento dichiarazioni e di definizione dei dati sono indicati nella API Object SQL tramite @SqlUpdate annotazione. I metodi per queste istruzioni devono avere tipi di ritorno vuoto o int. Se il tipo di ritorno è int, il valore sarà il numero di righe modificate.

Annota con @SqlUpdate. Ecco un esempio di utilizzo utilizzando h2 come DB.

DBI dbi = new DBI("jdbc:h2:mem:test"); 
Handle h = dbi.open(); 
Dao1 dao1 = h.attach(Dao1.class); 
dao1.save(myBean1); 

Riferimento: http://jdbi.org/sql_object_api_dml

2

Il SQL Object API Overview mostra la possibilità di legare due istanze per lo stesso handle. In questo modo è possibile sia save() chiamate come parte della stessa transazione:

// TODO: add try/catch/finally to close things properly 
DBI dbi = new DBI("jdbc:h2:mem:test"); 
Handle h = dbi.open(); 
h.begin(); 
Dao1 dao1 = h.attach(Dao1.class); 
Dao2 dao2 = h.attach(Dao2.class); 
dao1.save(myBean1); 
dao2.save(myBean2); 
h.commit(); 
h.close(); 

Se si utilizza onDemand invece di open e esitate a try/catch a destra, si potrebbe prendere in considerazione qualcosa di simile:

// add some more interfaces 
public interface Dao1 extends GetHandle, Transactional<Dao1> { 
    @Query("insert into table1 ...") 
    save(myBean1); 
} 

DBI dbi = new DBI("jdbc:h2:mem:test"); 
Dao1 dao1 = dbi.onDemand(Dao1.class); 

// no try/catch necessary here 
dao1.inTransaction(transactional, status) -> { 
    transactional.save(myBean1); 
    transactional.withHandle((h) -> h.attach(Dao2.class) 
     .save(myBean2)); 
    return null; // return is enforced by the interface 
}); 

Si prega di ricontrollare la funzionalità con un test dell'unità.

0

È possibile utilizzare la transazione di richiamata su DBI:

dbi.useTransaction((handle, transactionStatus) -> { 
    Dao1 dao1 = handle.attach(Dao1.class); 
    Dao2 dao2 = handle.attach(Dao2.class); 
    dao1.save(); 
    dao2.save(); 
}); 

Supponendo che si sta utilizzando JDBI v2.x

Problemi correlati