transacciones example ejemplo java hibernate jpa ejb

example - jpa java



JPA utilizando la alternativa "persistence.xml" (6)

Sé que con la instrucción:

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

El mecanismo de persistencia JPA lee el archivo "persistence.xml", busca la unidad de persistencia llamada "nombre-unidad de persistencia" y construye el EntityManagerFactory basado en él.

Mi pregunta es, ¿cómo puedo forzar a JPA a tomar un archivo diferente de "persistence.xml" ? por ejemplo, "persistence-test.xml".


Así que queremos tener 2 archivos persistence.xml separados. Uno debe leerse solo por la configuración de producción, y el otro para pruebas. La idea es renombrar u ocultar los archivos de producción .

Solución de guerra

No ponga persistence.xml en src/main/resources/META-INF/ . En su lugar, póngalo en src/main/webapp/WEB-INF/classes/META-INF/ . Esa es la ubicación donde debería estar el archivo y en este lugar no será visible mediante pruebas.

Esta solución funciona para mí en el entorno de Gradle, pero espero que en otros también lo haga.

Solución de tarro

Cambie el nombre del archivo de producción a persistence-ee.xml . Ahora hemos terminado con la configuración de prueba. Para la producción debemos emplear algún procesamiento. Cada entorno puede tener su propio camino, así es como lo hago en Gradle:

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

En mis aplicaciones, el archivo persistence.xml para producción solo es necesario en el momento del despliegue, es decir, en los paquetes jar / war. Y estos son los únicos lugares donde este archivo es visible. Sin doble persistence no pude iniciar mi base de datos. La razón principal fue el uso de jta-data-source , la otra: 2 unidades de persistencia con nombre separadas.


En EclipseLink puedes hacer lo siguiente:

Properties pros = new Properties(); pros.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/persistence-alternative.xml"); EntityManagerFactory factory = Persistence.createEntityManagerFactory("pu-name", pros);



No hay una forma JPA estandarizada para hacer esto, aunque los proveedores de JPA individuales pueden proporcionar una forma. Sugeriría la forma estándar de tener una ruta de clase diferente para main y test.

Por ejemplo, si usa Maven y tiene dos archivos META-INF/persistence.xml , uno en src/main/resources y otro en src/test/resources , las pruebas recogerán el de src/test/resources , porque Maven coloca las clases / recursos de prueba por delante de las clases / recursos principales en el classpath. Puede configurar fácilmente Ant para que funcione de manera similar.

Si necesita una lógica más avanzada, considere usar el soporte JPA de Spring . Le permitirá lidiar con situaciones avanzadas como la integración de múltiples archivos persistence.xml .


Puede configurar Hibernate sin usar persistence.xml en Spring de esta manera:

@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; }

Como no está utilizando persistence.xml, debe crear un bean que devuelva DataSource que especifique en el método anterior que establece el origen de datos:

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

Luego usa la anotación @EnableTransactionManagement sobre este archivo de configuración. Ahora, cuando pones esa anotación, debes crear un último bean:

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

Ahora, no se olvide de usar @Transactional Annotation sobre aquellos métodos que tratan con DB.

Por último, no olvide inyectar EntityManager en su repositorio (esta clase de repositorio debe tener @Repository anotación de @Repository ).