2010-06-08 23 views
5

Tengo una aplicación web Java que aprovecha JPA. La instancia de la base de datos se especifica en el archivo persistence.xml con la etiqueta jta-data-source.¿Cómo "parametrizar" la instancia de la base de datos JPA en persistence.xml?

Me gustaría implementar una segunda copia de la aplicación web en el mismo servidor (glassfish), pero apunté a una instancia de base de datos diferente.

¿Cuál es la mejor manera de lograr esto? Creo que, idealmente, me gustaría colocar un archivo de anulación persistence.xml fuera de la guerra (en algún lugar de la ruta de clase?). No estoy exactamente seguro de dónde ponerlo o cómo definirlo de una manera que no confíe con mi otra instancia. Puedo vernos hospedando un puñado de instancias de esta manera (SaaS) y me gustaría que la configuración esté fuera de la guerra implementada para que no se convierta en un problema de mantenimiento. Compartir una instancia de base de datos entre clientes no es una opción por razones de seguridad.

Estoy seguro de que este no es un problema exclusivo para nuestro grupo. ¿Cuáles son las mejores prácticas o soluciones que otros están utilizando para resolver este problema?

+0

Si tiene varias instancias únicas de la aplicación ejecutándose, ¿por qué no simplemente cambia el archivo persistence.xml para la segunda instancia? – kgrad

+0

Parece que es un problema de mantenimiento tener que hacer esto manualmente para cada instancia en cada compilación, me gustaría una solución automatizada. – Vinnie

Respuesta

1

i ¿Supongo que ya estás alterando la copia en otras cosas también? (por ejemplo, nombre del archivo ear)

Si utiliza un software de compilación como hormiga o maven, podría usar un marcador de posición dentro de persistence.xml y crear una "copia" diferente con solo usar diferentes parámetros de compilación.

p. Ej. con Maven

mvn instalación limpia -DmyDatabaseName = db/somedb

+0

OK, eso suena bien. ¿Qué debo colocar en mi persistence.xml como marcador de posición para que se produzca la sustitución de texto? – Vinnie

+1

vea el comentario de Pascal a continuación :-) –

+0

Tengo que encontrar una solución para hacer lo que hizo la pregunta original, ya que tengo que administrar unos 500 servidores en diferentes ubicaciones con diferentes conexiones. Más ideas, como hacer 500 guerras no es una buena: S – Vedran

1

Me empaquetar dos versiones de la aplicación web y declarar un origen de datos específico en el elemento jta-data-source de sus respectivos persistence.xml (no creo que se puede externalizar este archivo, se espera que esté en WEB-INF/classes/META-INF/persistence.xml)

+0

Ah, me temía eso. Construir varias veces para hacer un simple cambio de configuración parece un problema desde el punto de vista del mantenimiento a medida que la aplicación madura, se agregan más clientes y se lanzan nuevas versiones (10 clientes significa 10 ciclos separados de compilación e implementación con cambios en el archivo de persistencia entre medio) Yo uso Maven para compilar y empaquetar. ¿Sabes si hay un plugin maven que podría generar múltiples guerras, tomando el xml de persistencia apropiado para cada configuración? – Vinnie

+1

@Vinnie: Usaría [filtrado y perfiles] (http://www.sonatype.com/books/mvnref-book/reference/resource-filtering-sect-description.html) (y dejaría que mi motor de CI construya todo variantes usando una Matriz de compilación). Declare algo como ' $ {foo}' en su 'persistence.xml' y use Maven para filtrar el valor. –

2

actualización:

http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html

no está seguro de si esto se puede configurar en un servidor de aplicaciones, pero lo voy a dar una ir. Lo único que me preocupa es la gestión del alcance. el contenedor gestiona el alcance a lo largo de límites de transacción

//inject entity manager 
@Inject("mySpecialEntityManager") 
EntityManager em; 

//then mark the actual factory method in the factory bean with  
@Produces("mySpecialEntityManager") 

pero entonces cómo administrar ámbito de aplicación es el problema


2.2.2. Bootstrapping

La especificación JPA define un procedimiento de arranque para acceder a EntityManagerFactory y EntityManager. La clase de arranque es javax.persistence.Persistence, p.

Map configOverrides = new HashMap();

configOverrides.put ("hibernate.hbm2ddl.auto", "create-drop");

EntityManagerFactory programmaticEmf =

Persistence.createEntityManagerFactory("manager1", configOverrides); 

La primera versión es equivalente a la segunda con un mapa vacío.La versión del mapa es un conjunto de modificaciones que tendrá prioridad sobre las propiedades definidas en sus archivos persistence.xml. Todas las propiedades que se definen en la Sección 2.2.1, “Packaging” se pueden pasar al método createEntityManagerFactory y hay algunas otras adicionales:

* 

    javax.persistence.provider to define the provider class used 
* 

    javax.persistence.transactionType to define the transaction type used (either JTA or RESOURCE_LOCAL) 
* 

    javax.persistence.jtaDataSource to define the JTA datasource name in JNDI 
* 

    javax.persistence.nonJtaDataSource to define the non JTA datasource name in JNDI 
* 

    javax.persistence.lock.timeout pessimistic lock timeout in milliseconds (Integer or String) 
* 

    javax.persistence.query.timeout query timeout in milliseconds (Integer or String) 
* 

    javax.persistence.sharedCache.mode corresponds to the share-cache-mode element defined in Section 2.2.1, “Packaging”. 
1

¿Qué pasa con el almacenamiento de una persistence.xml en la carpeta META-INF de un classes directorio y luego especificando esa carpeta primero en el classpath?

0

Esto es lo que yo era capaz de hacer en un entorno Java SE:

Crear un archivo .jar sin el archivo persistence.xml . Creé un archivo manifest.mf manualmente y en el Class-Path: puse "." además de las otras entradas que necesitaba.

En el directorio donde instala el software, cree un directorio META-INF y ponga persistence.xml allí. Debería ser recogido automáticamente.

p. Ej.

/my/install/dir/ 
       META-INF/persistence.xml 
       foo.jar 
Cuestiones relacionadas