Подтвердить что ты не робот

JPA с использованием альтернативного "persistence.xml"

Я знаю, что с инструкцией:

Persistence.createEntityManagerFactory("persistence-unit-name");

Механизм сохранения JPA считывает файл "persistence.xml", ищет блок сохранения, называемый "persistence-unit-name", и создает на нем EntityManagerFactory.

Мой вопрос: как я могу заставить JPA взять файл, отличный от "persistence.xml" ? например, "persistence-test.xml".

4b9b3361

Ответ 1

Нет стандартизованного метода JPA для этого, хотя отдельные поставщики JPA могут предоставить способ. Я бы предложил стандартный способ иметь другой путь класса для основного и теста.

Например, если вы используете Maven, и у вас есть два файла META-INF/persistence.xml, один в src/main/resources и один в src/test/resources, тесты подберут значение в src/test/resources, потому что Maven помещает тестовые классы/ресурсы впереди основных классов/ресурсов в пути к классам. Вы можете легко настроить Ant на работу аналогичным образом.

Если вам нужна более сложная логика, рассмотрите возможность использования Spring поддержки JPA. Это позволит вам работать с такими расширенными ситуациями, как интеграция нескольких файлов persistence.xml.

Ответ 2

В EclipseLink вы можете сделать следующее:

Properties pros = new Properties();

pros.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, 
                 "META-INF/persistence-alternative.xml");


EntityManagerFactory factory = 
    Persistence.createEntityManagerFactory("pu-name", pros);

Ответ 3

Я не думаю, что ты можешь. Длинный способ сделать это:

  • Создайте Factory, который будет читать ваши persistence-test.xml и отображать свойства Map<String, String> и.
  • Вызвать Persistence.createEntityManagerFactory(persistenceUnitName, Map properties). Таким образом, он считывает с карты properties вместо чтения с persistence.xml.

Ответ 4

Если вы использовали OpenEJB для тестирования вашего тестирования, вы могли бы сделать именно то, что хотите, используя какой бы то ни было JPA-провайдер. Аналогичный вопрос и соответствующий ответ здесь:

Как указать Maven игнорировать мой main/resources/persistence.xml в пользу теста/...?

Ответ 5

Вы можете настроить Hibernate без использования persistence.xml вообще в Spring, например:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
Map<String, Object> properties = new Hashtable<>();
properties.put("javax.persistence.schema-generation.database.action",
"none");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); //you can change this if you have a different DB
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(adapter);
factory.setDataSource(this.springJpaDataSource());
factory.setPackagesToScan("package name");
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
factory.setValidationMode(ValidationMode.NONE);
factory.setJpaPropertyMap(properties);
return factory;
}

Поскольку вы не используете persistence.xml, вы должны создать bean, который возвращает DataSource, указанный вами в указанном выше методе, который устанавливает источник данных:

@Bean
public DataSource springJpaDataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:mysql://localhost/SpringJpa");
dataSource.setUsername("tomcatUser");
dataSource.setPassword("password1234");
return dataSource;
}

Затем вы используете аннотацию @EnableTransactionManagement по этому файлу конфигурации. Теперь, когда вы помещаете эту аннотацию, вам нужно создать последний bean:

@Bean
public PlatformTransactionManager jpaTransactionManager()
{
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject());
}

Теперь не забудьте использовать @Transactional Аннотацию к тем методам, которые относятся к БД.

Наконец, не забудьте ввести EntityManager в ваш репозиторий (этот класс репозитория должен иметь аннотацию @Repository над ним).

Ответ 6

Итак, мы хотим иметь 2 отдельных файла persistence.xml. Один должен быть прочитан только по конфигурации производства, а другой для тестов. Идея состоит в том, чтобы переименовать или скрыть файлы.

Военное решение

Не помещайте persistence.xml в src\main\resources\META-INF\. Вместо этого поместите его в src\main\webapp\WEB-INF\classes\META-INF\. Это место, где должен находиться файл, и в этом месте оно не будет видно по тестам.

Это решение работает для меня в среде gradle, но я надеюсь, что и в других тоже будет.

Решение Jar

Переименуйте производственный файл в persistence-ee.xml. Теперь мы закончили с тестовой конфигурацией. Для производства мы должны использовать некоторую обработку. Каждая среда может иметь свой собственный путь, как я это делаю в gradle:

tasks.withType(Jar) {
  rename { fileName ->
    fileName == "persistence-ee.xml" ? "persistence.xml" : fileName;
  }
}

В моих приложениях, имеющих файл persistence.xml для производства, требуется только во время развертывания, то есть в jar/war-пакетах. И это единственные места, где этот файл виден. Без double persistence я не мог запустить свою базу данных. Основная причина заключалась в использовании jta-data-source, другой: 2 отдельных именованных модуля сохранения.