JPA с использованием альтернативы "persistence.xml" - PullRequest
21 голосов
/ 29 августа 2011

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

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

Механизм персистентности JPA считывает файл «persistence.xml», ищет модуль персистентности, называемый «persistence-unit-name», и создает EntityManagerFactoryоснованный на этом.

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

Ответы [ 6 ]

18 голосов
/ 29 августа 2011

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

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

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

15 голосов
/ 12 апреля 2012

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

Properties pros = new Properties();

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


EntityManagerFactory factory = 
    Persistence.createEntityManagerFactory("pu-name", pros);
4 голосов
/ 29 августа 2011

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

  • Создать фабрику, которая будет читать ваши persistence-test.xml и отображать Map<String, String> свойства, и.
  • Позвонить Persistence.createEntityManagerFactory(persistenceUnitName, Map properties).Таким образом, он читает с карты properties вместо чтения с persistence.xml.
2 голосов
/ 19 июня 2017

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

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

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

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

Раствор в банке

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

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

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

1 голос
/ 06 апреля 2017

Вы можете настроить 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
public PlatformTransactionManager jpaTransactionManager()
{
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject());
}

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

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

1 голос
/ 04 сентября 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...