Бесконечная рекурсия в методе flush () с Hibernate - PullRequest
0 голосов
/ 05 сентября 2011

Я считаю, что это странная проблема, но она уходит!

В контексте: я реализую свой тест JUnit и тестирую класс под названием songJPA.Я создаю песню (ОК), затем я создаю песню с тем же именем, и я ожидаю исключения (ОК), и, наконец, я хотел бы удалить первое создание песни (чтобы не было ошибки во время следующего теста выполнения).

Проблема в том, что когда я выполняю DeleteSongTest () по отдельности, он работает и удаляет мою песню, но когда я исполняю все из них, он не работает, он входит в бесконечную рекурсию.Я думаю, что это происходит в методе flush (), и я попытался отладить, но это невозможно.

Я вставляю все классы, с которыми я работаю.

JUNIT TEST CLASS:

public class SongCRUDTest {

private SongJPA testSong1;
private SongJPA testSong2;
private SongJPAJpaController slc;

@Before
public void setUp() {
    testSong1= new SongJPA("TestTitle", 120, 19, new SongInfoJPA(), "TestArtist", Genre.CLASSICAL);
    testSong2= new SongJPA("TestTitle", 122, 12, new SongInfoJPA(), "TestArtist2", Genre.BLUES);
    slc =  new  SongJPAJpaController();
}

@Test
public void A_createSong(){
    slc.create(testSong1);
}


@Test(expected = PersistenceException.class)
public void B_createDuplicatedTestSong() {
    slc.create(testSong2);
}   

@Ignore
@Test
public  void C_deleteSong() throws NonexistentEntityException{
    SongJPA songToDelete= slc.findSongJPAByTitle("TestTitle");
    if(songToDelete!=null)
        slc.destroy(songToDelete.getId());
}

Метод уничтожения, который работает, только когда я выполняю по отдельности.(Из шаблона netbeans)

 public void destroy(int id) throws NonexistentEntityException {
    EntityManager em = null;
    try {
        em = getEntityManager();
        em.getTransaction().begin();
        SongJPA songJPA;
        try {
            songJPA = em.getReference(SongJPA.class, id);
            songJPA.getId();
        } catch (EntityNotFoundException enfe) {
            throw new NonexistentEntityException("The songJPA with id " + id + " no longer exists.", enfe);
        }
        em.remove(songJPA);
        em.flush();
        em.getTransaction().commit();
    } finally {
        if (em != null) {
            em.close();
        }
    }
}

EDITION1: метод create ()

public void create(SongJPA songJPA) { EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); em.persist(songJPA); em.getTransaction().commit(); } finally { if (em != null) { em.close(); } } }

enter image description here

Секунды спустя

54587 [main] WARN org.hibernate.util.JDBCExceptionReporter - Ошибка SQL: 1205, SQLState: 41000 54587 [main] ОШИБКА org.hibernate.util.JDBCExceptionReporter - Превышено время ожидания блокировки;попробуйте> перезапустить транзакцию

TIA для помощи !!!!

1 Ответ

2 голосов
/ 05 сентября 2011

Как только вы получаете исключение из метода JPA, вы должны учитывать, что транзакция должна быть откатана, а EM должен быть закрыт: кэш первого уровня находится в плохом состоянии и не может быть восстановлен. Подробнее см. http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html_single/#transactions-demarcation-exceptions.

Используйте EM.find вместо EM.getReference и проверьте на ноль. getReference используется, когда вы знаете, сущность с данным идентификатором существует. И, таким образом, он выдает исключение, если позже выясняется, что это не так, но уже слишком поздно. Принимая во внимание, что find выполняет запрос, чтобы получить состояние сущности, и возвращает ноль, если он не существует. Вы можете создать объект, если он еще не существует, или удалить его, если он существует.

Более того, похоже, что вы ожидаете, что тесты будут выполняться в фиксированном порядке. Ты не должен. Каждый модульный тест должен выполняться отдельно и должен выполняться независимо от того, был ли ранее выполнен тест. Используйте метод, отмеченный @After, чтобы выполнить очистку после каждого теста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...