2011-07-26 2 views
2

У меня проблема при тестировании моего DAOObject. У меня есть две сущности, которые связаны отношением @oneToOne. Классы:Spring, Hibernate @OneToOne Проблема с транзакционным тестом

@Entity 
@Table 
public class Device extends HyEntity { 

    @OneToOne(mappedBy = "device") 
    private EndUser endUser; 
    //getters+setters 
} 

и

@Entity 
@Table 
public class EndUser extends HyEntity { 

    private String firstname; 
    private String lastname; 
    @OneToOne 
    private Device device; 
    //getters+setters 
} 

В DAO я делаю следующее:

Device d1 = new Device(); 

    EndUser e1 = new EndUser(); 
    e1.setFirstname("Hans"); 
    e1.setLastname("Muster"); 
    e1.setDevice(d1); 

    repo.saveEntity(d1); 
    repo.saveEntity(e1); 
    sf.getCurrentSession().flush(); 
    repo.updateEntity(d1); 
    sf.getCurrentSession().flush(); 

    Assert.notNull(repo.getEndUserById(e1.getId())); 
    Assert.notNull(repo.getEndUserById(e1.getId()).getDevice()); 
    Assert.notNull(repo.getDeviceById(d1.getId())); 

    sf.getCurrentSession().flush(); 
    d1 = repo.getDeviceById(d1.getId()); 
    Hibernate.initialize(d1); 
    Hibernate.initialize(d1.getEndUser()); 
    Assert.notNull(repo.getDeviceById(d1.getId()).getEndUser()); //FAILS endUser of Device is always NULL 

Как вы можете видеть, ни session.flush(), ни Hibernate.Initalize работает. Устройство EndUser не относится к устройству. Если я удалю @Transactional, ... все работает так, как должно. Есть ли способ заставить это работать? В противном случае мне всегда придется удалять созданные объекты в базе данных вручную после теста, что довольно неприятно.

Надеясь на ответ.

Спасибо заранее.

+0

Возможно, 'd1.setEndUser (e1)' помогает? – marc

+1

Это поможет. Я думаю, что дело в том, что оно работает в соответствии с не транзакционными тестами, а не в транзакционных тестах. – chzbrgla

+1

Да, это работает, если я добавлю 'd1.setEndUser (e1);' Но это просто обходной путь ... Я думаю, что должно быть возможно заставить это работать без такого обходного пути. Без @transactional он работает ... – drame

ответ

1

После последнего флеша вам необходимо добавить clear(). Если вы пропустите это, то hibernate вернет точно тот же самый экземпляр из своего внутреннего кеша, где релиз не обновляется.

Во всяком случае, по моему личному мнению, плохая практика не устанавливать отношения корабля с обеих сторон вручную. - Потому что, если вы не устанавливаете его с обеих сторон, вы всегда должны заботиться о том, чтобы объект перезагрузился из базы данных. И если вы не перезагружаете объект из базы данных, чем ... (см. Ваш тест).

+0

спасибо. clear() сделал трюк. Я заметил, что есть какой-то кеш, но я не понял, что это было в сеансе, и что clear() будет, очистите его. ^^ – drame

Смежные вопросы