Вступление
В своем предыдущем посте я объявил о своем намерении создать персональный курс 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
|
@Entity class 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
|
@Test public 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
|
@Override 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" , "" ); 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
|
@Override protected 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 Влада Михалча в блоге Влада Михалча . |