2011-03-08 3 views
1

최대 절전 모드를 사용하여 데이터베이스에 항목을 삽입 할 수 있는지 확인하는 테스트를 설정했습니다. 나를 미치게하는 것은 Hibernate가 항목이 삭제되지 않는다는 것이다.Hibernate가 내 객체를 삭제하지 않습니다. 왜?

아래의 테스트가 성공적으로 수행되었지만 나중에 DB를 검사 할 때 삽입 된 항목이 그대로 남아 있습니다! 나는 심지어 어설트을 사용하여 그것을 체크하려고한다. (예, 나는 -ea를 vm 매개 변수로 가진다.) 항목이 삭제되지 않는 이유는 누구입니까?

public class HibernateExportStatisticDaoIntegrationTest { 
    HibernateExportStatisticDao dao; 
    Transaction transaction; 

    @Before 
    public void setUp(){ 
     assert numberOfStatisticRowsInDB() == 0; 
     dao = new HibernateExportStatisticDao(HibernateUtil.getSessionFactory()); 
    } 

    @After 
    public void deleteAllEntries(){ 
     assert numberOfStatisticRowsInDB() != 0; 
     Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
     for(PersistableStatisticItem item:allStatisticItemsInDB()) { 
      session.delete(item); 
     } 
     session.flush(); 
     assert numberOfStatisticRowsInDB() == 0; 
    } 

    @Test public void exportAllSavesEntriesToDatabase(){ 
     int expectedNumberOfStatistics = 20; 
     dao.exportAll(StatisticItemFactory.createTestStatistics(expectedNumberOfStatistics)); 

     assertEquals(expectedNumberOfStatistics, numberOfStatisticRowsInDB()); 
    } 

    private int numberOfStatisticRowsInDB() { 
     return allStatisticItemsInDB().size(); 
    } 

    @SuppressWarnings("unchecked") 
    private List<PersistableStatisticItem> allStatisticItemsInDB(){ 
     Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
     transaction = session.beginTransaction(); 
     Query q = session.createQuery("FROM PersistableStatisticItem item"); 
     return q.list(); 
    } 
} 

콘솔은

Hibernate: delete from UPTIME_STATISTICS where logDate=? and serviceId=? 

으로 가득하지만 난 그것을 확인할 때 아무 것도 삭제되지 않았습니다.

답변

4

트랜잭션의 일관성없는 사용과 관련이 있습니다 (해당 커밋없이 allStatisticItemsInDB()beginTransaction()이 여러 번 호출됨에 유의하십시오).

시도는 다음과 같이 예를 들어, 적절한 방법으로 트랜잭션을 관리하는 방법 : 또한

Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
Transaction tx = session.beginTransaction(); 
for(PersistableStatisticItem item: 
    session.createQuery("FROM PersistableStatisticItem item").list()) { 
    session.delete(item); 
} 
session.flush(); 
assert session.createQuery("FROM PersistableStatisticItem item").list().size() == 0; 
tx.commit(); 

참조 :

+0

적절한 Hibernate 사용법에 대한 지식이'nil'에 가깝다는 것을 알고있을 것입니다. 내일 다시 일하러 돌아올 때 어떻게 작동하는지 살펴볼 것입니다. 감사! – oligofren

+0

제공된 코드가 충분하지 않았더라도 트랜잭션이 원인이라는 것이 옳았습니다. 코드를 사용하는 경우 session.delete()에 도달하면 세션이 닫혔다는 예외가 발생합니다. 이유는 모르겠지만 각 논리적 연산 (아마도 여러 트랜잭션으로 구성)마다 새로운 세션을 여는 것이 더 합리적이라고 생각합니다. – oligofren

+0

꽤 끝나지 않았습니다 ... 모든 것을 작동 시키려면 기본적으로 제가 한 일입니다. 데이터베이스/최대 절전 모드 I에 대한 쿼리와 관련된 모든 방법에서 : - 새 세션을 열었습니다. 세션 세션 = HibernateUtil.getSessionFactory(). openSession(); - 새 트랜잭션을 시작했습니다. '세션. - 트랜잭션을 위탁 함 'session.flush(); ' 'session.getTransaction(). commit();' – oligofren

0

당신이 당신의 DB 스키마를 게시 할 수 및 HBM 또는 Fluent지도? 필자는 Fluent 맵에서 ReadOnly()를 사용했다. 그것은 결코 오류를 던지지 않았고 나는 또한 로그에서 "blahblah = ..."와 같은 "blah에서 삭제"를 보았습니다.

+0

나는 위의 거래 내역이 유익하다는 것을 확인한 후 내일, 그것을 시도 할 것이다. 감사! – oligofren

+0

문제를 일으킨 거래를 시작하거나 끝내는 것이 내 엉뚱한 방법으로 보입니다. 어쨌든 고마워. – oligofren

1

동일한 문제가 있습니다. 나는 전혀 거래를 사용하지는 않았지만. 나는 다음과 같이 namedQuery를 사용했습니다 :

Query query = session.getNamedQuery(EmployeeNQ.DELETE_EMPLOYEES); 
int rows = query.executeUpdate(); 
session.close(); 

2 행을 반환했지만 데이터베이스에는 여전히 모든 레코드가 있습니다. 그런 다음 위의 코드를 다음과 같이 마무리합니다.

Transaction transaction = session.beginTransaction(); 
Query query = session.getNamedQuery(EmployeeNQ.DELETE_EMPLOYEES); 
int rows = query.executeUpdate(); 
transaction.commit(); 
session.close(); 

그런 다음 제대로 작동하기 시작했습니다. SQL 서버를 사용하고있었습니다. 하지만 h2를 사용하면 위의 코드 (트랜잭션없이)도 제대로 작동합니다. 한 가지 더 관찰 : 트랜잭션의 레코드 사용을 삽입하고 가져 오는 것은 필수는 아니지만 레코드를 삭제하려면 트랜잭션을 사용해야합니다. (SQL 서버에서만 테스트 됨)

관련 문제