Spring: разрешить отсутствие подключения к базе данных
У меня есть проект, подключенный к нескольким базам данных (Oracle и SQLServer), некоторые из которых не всегда являются обязательными или доступными при запуске приложения, особенно в среде разработки.
Я ищу способ разрешить запуск приложения без подключения к базе данных. Нам требуется подключение к этой БД только при выполнении определенных задач, в которых используется промежуточная база данных, требующая определенного доступа к сети, который не всегда доступен для разработчиков.
Здесь с нашим подключением к Oracle (которое находится в определенной сети):
У нас была конфигурация, которая позволяла запускать приложение, но выдавала ошибки при запуске тестов из-за ошибочного приведения HikariDataSource:
Я переместил эту конфигурацию, чтобы расширить HikariConfig следующим образом:
Что не запускается, если база данных Oracle недоступна. Использование встроенной БД не подходит для нашего случая использования, поскольку нам не всегда нужно это соединение, а когда нам нужно, нам нужны определенные данные, реплицированные из производственной среды. Разделение этого на несколько микросервисов / приложений также недопустимо, поскольку это было бы огромным рефакторингом и не совсем подходит для нашего варианта использования (мы объединяем данные из нескольких источников в окончательный).
Бин службы модульного тестирования, который использует Spring + JPA, но БД недоступна
Простое банковское приложение: 
- Использование Spring + JPA с EclipseLink в качестве поставщика JPA
- EntityManager вводится в BaseDaoImpl с использованием @PersistenceContext
- DAO автоматически подключаются к сервисному компоненту
- @Transactional аннотация, используемая в методах обслуживания
Цель: методы обслуживания модульного тестирования как часть сборки maven
Unit-test = простое тестирование API. Например, сервисный метод: transfer(int fromAccountId, int toAccountId, double amount) имеет модульные тесты:
- fromAccountId не должно быть 0
- toAccountId не должно быть 0
- fromAccountId знак равно toAccountId
- `сумма больше 0
- и т.п.
Эти «модульные» тесты не требуют подключения к БД.
Проблема: на сервере сборки не настроена БД. Однако, когда выполняется тестовый пример, Spring пытается подключиться к БД, но это не удается. Однако в этих случаях нам не требуется подключение к БД. (У нас есть еще один набор «случаев интеграции» — они не выполняются как часть обычной сборки, но будут выполняться вручную с доступной полной средой. Как? — См. Этот поток )
- Каковы лучшие практики для выполнения таких типов модульных тестов?
- Можем ли мы заставить Spring не устанавливать соединение с БД до последней минуты, когда оно действительно необходимо? (Прямо сейчас, когда он встречает @Transactional метод)
Добавление кода уровня обслуживания по запросу:
То, что вам нужно, недалеко от интеграционного теста. Сначала вам нужно собрать манекен PlatformManager и убедиться, что он используется для вашего теста. Вы найдете подсказки для этого в другом посте на SO. Как издеваться над TransactionManager в тесте JUnit (вне контейнера)? и еще один (частичный) пример ниже.
Поскольку Spring применяет ApplicationContext определение по порядку, последнее перекрывает другие, вы просто добавляете для себя тестовый файл xml (или JavaConfig) в последнем месте, объявляя этот фиктивный файл PlatformManager с тем же именем bean, что и в обычной конфигурации.
Затем вы получаете свой служебный компонент из контекста приложения и заменяете его Dao на макет (Mockito или что вам нравится).
В зависимости от того, что вам нужно протестировать, вам придется настроить манекен PlatformManager , но если вы просто добавите:
вы сможете контролировать запуск, фиксацию или откат транзакции. Если у вас есть особые требования, вам может потребоваться создать реальное значение SimpleTransactionStatus вместо передачи null.
БД сервера H2, созданная с помощью Spring, недоступна
Раньше у меня была рабочая установка, в которой я создаю сервер H2 и источник данных, используя свой applicationContext при развертывании файла войны. Моя конфигурация такая:
Затем я определил
С jpaProperty, определенным, чтобы позволить спящему режиму автоматически генерировать все таблицы:
Это работает как шарм, и когда мое приложение развертывается, все таблицы создаются автоматически. Это отлично подходит для тестовой установки, но для производственной версии мы хотели бы отключить автоматическое создание таблиц с помощью спящего режима, и мы хотим сами управлять сценариями создания и миграции sql.
Поэтому я решил использовать пролет в качестве инструмента миграции БД и удалил следующую строку из определения EntityManager:
Кажется, это работает, и база данных создана и имеет минимальный размер, но когда я пытаюсь подключиться к ней с помощью Squirrel, я получаю следующее исключение:

Я ожидал, что если компоненты H2Server и источника данных созданы Spring, БД будет доступна с помощью драйвера, URL-адреса, имени пользователя и пароля.
Моя первая идея заключалась в том, что они не были созданы из-за ленивой инициализации, в то время как создание таблицы гибернации подразумевает, что bean-компоненты действительно инициализируются. Я попытался установить для свойства ленивой инициализации значение false для обоих свойств, но не повезло .
Должно быть, мне чего-то не хватает, но я пока не вижу . Есть ли способ сделать БД доступной для подключений после развертывания приложения?