Вступление
В своем предыдущем посте я объявил о своем намерении создать персональный курс Hibernate. Первое, с чего нужно начать — это минимальная конфигурация тестирования. Примеры актуальны для Hibernate 4 .
Вам нужен только Hibernate
В реальной производственной среде вы не будете использовать только Hibernate, поскольку можете интегрировать его в контейнер JEE или Spring. Для тестирования функций Hibernate вам не нужен полноценный стек фреймворка, вы можете просто положиться на гибкие параметры конфигурации Hibernate.
Случай 1: Конфигурация JDBC на основе драйвера
Сначала мы определяем тестовую сущность:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
@Entityclass SecurityId { @Id @GeneratedValue private Long id; private String role; public Long getId() { return id; } public String getRole() { return role; } public void setRole(String role) { this.role = role; }} |
Благодаря уровню абстракции Hibernate Transaction мы не вынуждены нанимать какого-либо внешнего менеджера транзакций или писать какой-либо самодельный код управления транзакциями.
В целях тестирования мы можем использовать локальные транзакции ресурса JDBC, которые внутренне управляются JdbcTransactionFactory по умолчанию.
Нам даже не нужно предоставлять внешний источник данных, поскольку Hibernate поставляется с непроизводственным встроенным пулом соединений, представленным DriverManagerConnectionProviderImpl .
Наш тестовый код выглядит так:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@Testpublic void test() { Session session = null; Transaction txn = null; try { session = sf.openSession(); txn = session.beginTransaction(); SecurityId securityId = new SecurityId(); securityId.setRole("Role"); session.persist(securityId); txn.commit(); } catch (RuntimeException e) { if ( txn != null && txn.isActive() ) txn.rollback(); throw e; } finally { if (session != null) { session.close(); } }} |
Нам не нужен внешний файл конфигурации, поэтому мы можем построить и настроить фабрику сессий:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@Overrideprotected SessionFactory newSessionFactory() { Properties properties = new Properties(); properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"); //log settings properties.put("hibernate.hbm2ddl.auto", "update"); properties.put("hibernate.show_sql", "true"); //driver settings properties.put("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver"); properties.put("hibernate.connection.url", "jdbc:hsqldb:mem:test"); properties.put("hibernate.connection.username", "sa"); properties.put("hibernate.connection.password", ""); return new Configuration() .addProperties(properties) .addAnnotatedClass(SecurityId.class) .buildSessionFactory( new StandardServiceRegistryBuilder() .applySettings(properties) .build() );} |
Случай 2: использование профессионального пула соединений
Если мы хотим заменить встроенный пул соединений профессиональным, Hibernate предлагает выбор настройки c3p0, которая обрабатывается внутри C3P0ConnectionProvider .
Нам нужно только изменить свойства конфигурации фабрики сеанса:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
protected SessionFactory newSessionFactory() { Properties properties = new Properties(); properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"); //log settings properties.put("hibernate.hbm2ddl.auto", "update"); properties.put("hibernate.show_sql", "true"); //driver settings properties.put("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver"); properties.put("hibernate.connection.url", "jdbc:hsqldb:mem:test"); properties.put("hibernate.connection.username", "sa"); properties.put("hibernate.connection.password", ""); //c3p0 settings properties.put("hibernate.c3p0.min_size", 1); properties.put("hibernate.c3p0.max_size", 5); return new Configuration() .addProperties(properties) .addAnnotatedClass(SecurityId.class) .buildSessionFactory( new StandardServiceRegistryBuilder() .applySettings(properties) .build() );} |
Случай 3: Использование внешнего источника данных
Поскольку Hibernate не регистрирует подготовленные операторы SQL параметры:
|
1
|
o.h.SQL - insert into SecurityId (id, role) values (default, ?) |
Мы добавим источник данных-прокси для перехвата реальных запросов SQL:
|
1
|
n.t.d.l.SLF4JQueryLoggingListener - Name: Time:0 Num:1 Query:{[insert into SecurityId (id, role) values (default, ?)][Role]} |
Конфигурация выглядит так:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
@Overrideprotected SessionFactory newSessionFactory() { Properties properties = new Properties(); properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"); //log settings properties.put("hibernate.hbm2ddl.auto", "update"); //data source settings properties.put("hibernate.connection.datasource", newDataSource()); return new Configuration() .addProperties(properties) .addAnnotatedClass(SecurityId.class) .buildSessionFactory( new StandardServiceRegistryBuilder() .applySettings(properties) .build() );}private ProxyDataSource newDataSource() { JDBCDataSource actualDataSource = new JDBCDataSource(); actualDataSource.setUrl("jdbc:hsqldb:mem:test"); actualDataSource.setUser("sa"); actualDataSource.setPassword(""); ProxyDataSource proxyDataSource = new ProxyDataSource(); proxyDataSource.setDataSource(actualDataSource); proxyDataSource.setListener(new SLF4JQueryLoggingListener()); return proxyDataSource;} |
Вывод
Это минимальная настройка конфигурации, необходимая для тестирования функций Hibernate. Я также использую эти конфигурации всякий раз, когда я отправляю отчет об ошибке Hibernate, сопровождаемый повторяющимся тестовым примером.
- Код доступен на GitHub .
| Ссылка: | Минимальная конфигурация для тестирования Hibernate от нашего партнера JCG Влада Михалча в блоге Влада Михалча . |