How to configure JPA at run time(specialy schema of tables) - java

I am using JPA and I use Entity XML mapping Files to config my persistence layer on the other hand I have multiple database schemas in an Oracle database
In the persistence configuration, i want to have only one EntityManagerFactory and in fact i want to have connection with database with only one schema(USER).
Statically, I can specify schema name one by one to my Entities in Mapping files like this:
<entity class="package.MyClass" name="MyClass">
<table name="MYTABLE" schema="mySchema"/>
My persistence provider in this project is: org.hibernate.ejb.HibernatePersistence
I want to use a placeholder for specifying schema and replace that when JPA scan mapping files to configure itself.
<entity class="package.MyClass" name="MyClass">
<table name="MYTABLE" schema="#placeholder"/>
at config time replace #placeholder with mySchema
Is anyway to do this?
Which part (class) in JPA scan XML mapping files and can i customize that class to do this replace for me?

I think you can use the bootstrap procedure to access the EntityManagerFactory and the EntityManager at runtime to override the properties.

Related

Spring Data JPA, Hibernate #Table

I have a problem:
My application has an MSSQL host in which there are 2 databases.
All my entities look at base number:
And one Entity should look at base
I can do this by specifying the base in the #Table parameter (schema = databasename.schema)
Is there any way to make the #Table (schema) parameter come from application.properties?
Yes, it is possible. Look at the following properties:
<property name="hibernate.default_catalog" value="crm"/>
<property name="hibernate.default_schema" value="analytics"/>
You can use the following properties in the spring boot application.properties:
spring.jpa.properties.hibernate.default_catalog=crm
spring.jpa.properties.hibernate.default_schema=analytics
Look also at the #Table annotation documentation. When you set the schema attribute hibernate uses this specified schema, otherwise it is used user default schema that you can provide via hibernate.default_schema.
Also you can try to write your custom schema name resolver. As it stated in the documentation for the hibernate.schema_name_resolver property:
By default, Hibernate uses the org.hibernate.dialect.Dialect#getSchemaNameResolver. You can customize how the schema name is resolved by providing a custom implementation of the SchemaNameResolver interface.

how can I use my dynamic JNDI datasources with JPA?

We have an application which uses multiple databases to store the same data for different countries.
For example a Subscription object might be associated with Germany or Spain. If it's a German subscription, it needs to be stored in a different database to the Spanish subscriptions. The databases are identical in structure, but they have different contents.
We are running on jboss 5, and have a different datasource config (*ds.xml) file for each one, generated dynamically at startup. They are stored in JNDI - so we have DataSourceDE, DataSourceES, etc.
Here's how it should work: if a request comes in saying 'fetch subscription 17 for Germany' then I calculate that the datasource should be DataSourceDE and use JPA / hibernate to go fetch that object from the correct database. There will be a subscription 17 in the Spanish database too, which I don't want in this example.
I can generate the persistence.xml automatically to create the extra persistence units for the datasources, but the Subscription class is annotated with the following:
#PersistenceContext(unitName="core")
This is not going to work - how can I set the persistence context on the java object dynamically?
What you are trying to achieve is known as Multi-Tenancy. Here is a perfectly suitable tutorial for your question to make it work.
The main idea is to use a Stateless session bean which has a reference to both persistence units. Depending on what has to be done, this bean does a lookup to call the corresponding EntityManager. Furthermore here:
Multi-Tenancy With EJB 3.1 and JPA 2.0
You can change the persistence context for the EntityManager at runtime like this:
EntityManagerFactory emf =
Persistence.createEntityManagerFactory(persistenceUnitName);
EntityManager em = emf.createEntityManager();

how can I use persistence.xml to configurate apache-common-dbutils?

JPA is pretty good for immutable tables but I can't handle dynamic table.
Then I decide to use JPA for handle al the unalterable tables (the core of the application) and dbutils from apache to handle all my the dynamic tables
Both kind of tables are in the same database and I want to define the configuration of the database only in a single file
I define the jpa in a property file:
javax.persistence.jdbc.driver=com.mysql.jdbc.Driver
javax.persistence.jdbc.user=root
javax.persistence.jdbc.password=*****
javax.persistence.jdbc.url=jdbc:mysql://localhost:3306/database
But dbutils use the class "datasource" to configurate.
I didn't find how to get a "Datasource" from de "EntityManagerFactory" of jpa.
Or to get a instance of "EntityManagerFactory" from a "Datasource".
An EMF can be created for a (javax.sql.)DataSource by specifying the persistence-unit "jta-data-source" or "non-jta-data-source" (the JNDI name for the DataSource). So create the DataSource, make it accessible via JNDI, and then you can use it in the EMF and this "dbutils".

Modify persistence.xml on runtime

I'm developping a program that uses JPA, and I deployed it in a single jar. I wish to modify (or ask to the user, in an menĂº item) the configuration of the connection data with the database server.
It's possible to modify the data (user, password, ip) of the server "on the fly"?
(I apologize my bad english)
how about making a HashMap<String,Object> containing your options and passing it to Persistence.createEntityManagerFactory("unitName",map)?
From the Docs:
public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties)
Create and return an EntityManagerFactory for the named persistence unit using the given properties.
Source
The JPA spec doesn't allow for dynamic modification of persistence-units. Some implementations may provide an implementation-specific way of defining a persistence-unit dynamically. With DataNucleus JPA we do it as per the foot of this page

Getting values from persistence.xml

I have a persistence.xml file using JDBC, working fine, but the code updates the information in it as users change databases. What's best practice for reading out the current database from the javax.persistence.jdbc.url property? Parse the file as XML or can I load the information into some persistence unit object by passing the name to it?
You can access a persistence unit as follows:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("some_unit_name");

Categories