2012-06-21 4 views
1

Я использую Hibernate 4.0.1.Final в автономном приложении. Базой db является MySQL 5.5. Используя JUnit 4.8.1, я тестирую свой объект доступа к данным и хочу запускать тесты, чтобы, когда мой тест JUnit заканчивается, все мои изменения откатываются назад. Есть ли элегантный способ сделать это? Прямо сейчас все совершается, что имеет смысл. Вот мой JUnit тест ...Hibernate: как откат транзакций после теста JUnit?

@Before 
public void setUp() throws IOException { 
    final InputStream in = getClass().getClassLoader().getResourceAsStream("test.properties"); 
    testProps = new Properties(); 
    testProps.load(in); 
    final Configuration configuration = new Configuration(); 
    configuration.configure().setProperty("hibernate.show_sql", "false"); 
    final ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); 
    sessionFactory = configuration.buildSessionFactory(serviceRegistry); 
    orgDao = new OrganizationDAOImpl(sessionFactory); 
} // setUp 

@Test 
public void testInsertSchool() { 
    final Organization org = new Organization(); 
    org.setOrganizationId(testProps.getProperty("test.id")); 
    org.setName(testProps.getProperty("test.name")); 
    orgDao.saveOrUpdate(org); 
    final Organization foundOrg = orgDao.findById(org.getOrganizationId()); 
    Assert.assertEquals(org, foundOrg); 
} 

Вот код из объекта доступа к данным ...

protected void saveOrUpdate(Object obj) { 
    try { 
     startOperation(); 
     session.saveOrUpdate(obj); 
     tx.commit(); 
    } catch (HibernateException e) { 
     handleException(e); 
    } finally { 
     session.close(); 
    } 
} 

protected Object find(Class clazz, Serializable id) { 
    Object obj = null; 
    try { 
     startOperation(); 
     obj = session.get(clazz, id); 
     tx.commit(); 
    } catch (HibernateException e) { 
     handleException(e); 
    } finally { 
     session.close(); 
    } 
    return obj; 
} 

ответ

1

Что я решил сделать, это использовать базу данных в памяти HSSql, как описано здесь - http://vageeshhoskere.wordpress.com/2011/06/16/unit-test-with-junit-for-hibernate-using-hsqldb-in-memory/. Таким образом, я могу неоднократно запускать тесты JUnit (на уровне сервиса) и быть гарантированным, что состояние мира будет одинаковым при каждом запуске.

0

Способ сделать это было бы отделить ваши коммиты и сеанс закрывается от ваших операций с базами данных. Я на самом деле думаю, что это лучше сделать так или иначе, потому что не каждая операция базы данных должна быть собственной транзакцией. Существенные преимущества имеют возможность использовать один и тот же сеанс в нескольких операциях и использовать одну и ту же транзакцию для нескольких операций.

То, как я охарактеризовал уровень транзакций, является проблемой бизнес-правил, поскольку они определяют атомные единицы работы на уровне базы данных. Он должен быть одним слоем из слоя, который абстрагирует операции спящего режима для сохранения, поиска и слияния. Heres почему:

  1. Делать это позволит намного большую гибкость в том, как разработать бизнес-правила вашего приложения для обработки новых случаев, в которых различные операции базы данных являются взаимозависимыми, не заставляя вас писать в этом объекте базы данных только на миллион способов обрабатывать различные правила транзакций для каждого случая.
  2. Не только это, перемещение этих операций позволяет вам достичь того, чего вы хотите в своих модульных тестах.
  3. Операции Open/Close стоят дорого, если вы делаете 5 запросов подряд, и нет причин для их участия в отдельном сеансе, вы не должны открывать и закрывать 5 сеансов.
+0

Я согласен с вашей точкой зрения о разделении операций db от коммитов. Я видел, что это достигнуто на уровне сервиса. Но тогда мой же вопрос возник бы - при тестировании уровня сервиса, как бы я структурировал JUnit-тест, чтобы после выполнения операций уровня обслуживания изменения базы данных откат? – Dave

+0

Это зависит от того, что вы пытаетесь проверить. Возможно, вы могли бы дать вашему уровню обслуживания базы данных режим имитации, а не совершать, если он находится в режиме симуляции? – hsanders

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