tengo una prueba JUnit @Transactional configurado y quiero persistir algunos datos de prueba a la base de datos y también comprobar si las asociaciones son correctos. Sin embargo, al probar las asociaciones, siempre evalúan nulo, aunque funciona en una prueba no transaccional.El uso de las asociaciones bidireccionales de objetos de dominio en @Transactional Junit Pruebas
I persisten dos objetos utilizando la anotación @Before:
@Before
public void testData() {
TestObjectOne o = new TestObjectOne();
o.setName("One");
repo.saveEntity(o); //autowired
TestObjectTwo t = new TestObjectTwo();
t.setOne(o);
t.setName("Two");
repo.saveEntity(t);
}
Al acceder a esos dos objetos en una prueba, consigo el instancias correctas:
TestObjectOne o = repo.getOneByName("One");
TestObjectOne t = repo.getTwoByName("Two");
Al comprobar sobre la asociación entre t
y o
, obtengo una referencia correcta porque definí explícitamente esa asociación:
Assert.assertNotNull(t.getOne());
Pero al comprobar en el revés, el objeto o
no se actualiza correctamente:
Assert.assertNotNull(o.getTwos());
La asociación se define en el objeto de dominio como
En One
:
@OneToMany(mappedBy = "one", fetch = FetchType.EAGER)
private List<Two> twos;
en Two
:
@ManyToOne(optional = false)
private One one;
Cuando tengo la prueba no se ejecute como @Transactional, funciona muy bien, sin embargo.
edición ahorro de los organismos situados en la prueba en lugar del método @Before, no hace ninguna diferencia.
despejando la sesión realmente hizo el trabajo. Gracias. sin embargo, siento que es un poco molesto ocuparse de la sesión durante la prueba mientras se maneja correctamente durante la primavera en un entorno de producción :(. ¿Hay alguna otra manera de probar esto? La prueba puede dar un falso positivo o un falso negativo porque olvidé enjuagar/borrar, lo que no tengo que hacer en el código de producción :( – chzbrgla
Si desea una transacción única con una reversión al final, no, no creo que haya otra forma. Eso es cómo funciona Hibernate: la entidad se llena con datos de db solo una vez, cuando se carga en la sesión actual. Cuando descargue la sesión Hibernate realizará la actualización de sus datos en DB, pero no cambiará las entidades en la sesión actual. De hecho, funcionará de la misma manera en el código de producción si lo llamaras en una sola transacción. Funcionará correctamente solo si llamas a 'cargar' en otra transacción después de 'guardar'. – Roadrunner
Para hacer las cosas un poco más fáciles I generalmente escribe una clase base para transacciones Pruebas ctional que @Autowires SessionFactory y tiene un único método 'flushAndClear()' que solo toma la sesión actual y llama a 'flush()' y 'clear()', pero aún necesita recordar llamarlo y recargar objetos antes de las aserciones . – Roadrunner