2016-04-19 11 views
0

aktualisiert Wert habe ich gelesen, Frühling bin mit und haben folgende junit-Methode:Frühling Transactional nicht

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:TestProject-spring-test.xml" }) 
@Transactional 
public abstract class BaseTest { 
[...] 

    @Test 
    public void testSaveLoadedObject() { 
     SubTestModel st = modelService.load(subTestPk); 

     st.setSimpleObject("testString"); 

     modelService.save(st); 

     //now reload the object to ensure that everything has been saved correctly 
     st = modelService.load(st.getId()); 
     s+= "\n#3 afterLoad: " + st.getSimpleObject(); 

     //fails: 
     Assert.assertTrue(st.getSimpleObject().equals("testString")); 
    } 
} 

ModelService-Methode:

@Autowired 
private JdbcTemplate db; 

@Override 
@Transactional(propagation = Propagation.REQUIRED) 
public void save(final ItemModel model, String newValue) { 
    db.update("UPDATE table SET column=? WHERE id=?", new Object[] { newValue, model.getId() }); 
} 

@Override 
public <T extends AbstractItemModel> T load(final int id) { 
    ... 
    DAO.loadValue(...) 
} 

DAO-Methode: @Autowired private JdbcTemplate db;

@Override 
public <T> T loadValue(final AbstractItemModel model, final String columnName) { 
     final String sql = "SELECT column FROM table WHERE id=" + model.getId(); 

    Object plain = db.queryForObject(sql, new RowMapper<Object>() { 
     @Override 
     public Object mapRow(ResultSet r, int rowNum) throws SQLException { 
      return r.getObject(columnName); 
     } 
    }); 

    return plain; 

} 

passiert folgendes:

ursprünglichen Wert: enter image description here

der neue Wert in der DB gespeichert ist (sichtbar, wenn "SET Sitzungstransaktion Isolationsstufe UNCOMMITTED" -Einstellung) in mysql .

getSimpleObject-Wert in DB = "teststring" enter image description here

* aber, wenn die Last-Methode aufgerufen wird, ist es den "alten" bekommt Wert (= Wert vor speichern) *

getSimpleObject-Wert in Debugger = "simpleObjectValue"

Warum kann der zuletzt gespeicherte Wert (in der gleichen Transaktion und Methode) nicht von der Load-Methode gelesen werden?

Sie sehen, dass es keine neue Transaktion erstellt. Auch die Einstellung der Isolationsstufe mit "@Transaction (isolation = READ_UNCOMMITTED)" über die gesamte Testmethode hilft nicht

Kann jemand dieses Geheimnis lösen?

Vielen Dank im Voraus!

+0

Es hängt alles davon ab, was die Lade- und Speichermethoden tun. Der Code ist wichtig. –

+0

Hallo. save führt eine jdbc-template aus. "INSERT INTO ...". load führt eine jdbctemplate..queryForObject (...) aus – Niko

+0

Benötigen Sie weitere Informationen? – Niko

Antwort

0

Ändern Sie die Propagierung in REQUIRES_NEW für Ihre Speichermethode (um die Änderung in der Datenbank zu bestätigen und eine neue Transaktion zu öffnen).

Oder noch besser, fügen Sie Flush Call nach dem Speichern in Ihrem Test (es ist besser, weil Sie Ihren Code nicht ändern, nur um es an Ihren Integrationstest anzupassen).

+0

Werden die Änderungen, die durch die Testmethode gemacht wurden, nach dem Beenden noch zurückgesetzt? weil das erforderlich ist, sonst würde ich es mit Testdaten füllen ... Ich brauche etwas wie "Ausführen einiger Methoden, die Daten erstellen und überprüfen und nach dem Abschluss alles zurückrollen" -> @transactional – Niko

+0

Wenn ich nicht Verwenden Sie Spring Transaktionsverwaltung und manuell einfügen und wählen Sie es durch jdbc in der gleichen Transaktion, es funktioniert gut. also muss hier etwas falsch sein ... – Niko

Verwandte Themen