Hibernate/JPA: Mapping entities to different databases - java

I have an application which manages 3 databases. I use hibernate with JPA on seam framework.
So I have a persitence.xml file with three persitence-unit like this (I remove properties for db2 and db3):
<persistence-unit name="db1" transaction-type="JTA" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>db1source</jta-data-source>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.connection.driver_class"
value="oracle.jdbc.driver.OracleDriver" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.default_schema" value="SI_TEC" />
<property name="hibernate.validator.apply_to_ddl" value="false" />
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.WeblogicTransactionManagerLookup" />
</properties>
</persistence-unit>
<persistence-unit name="db2" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>d2source</jta-data-source>
</persistence-unit>
<persistence-unit name="db3" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>d3source</jta-data-source>
</persistence-unit>
In my seam components.xml file, I create 3 managed-persistence-context to map seam with my hibernate configuration.
Finally, I have several entities and my problem is here. I need to persist some entities in db2 and other in db3. So database schema are different and when I deploy my application, I get this error:
org.hibernate.HibernateException: Missing table: PORTAILPERMISSION
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1113)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:139)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:349)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
Truncated. see log file for complete stacktrace
Because, the table PORTAILPERMISSION doesn't exist in db2.
My question is:
How to specify in entity class what database (or persitence-unit) must be used to validate entity in startup ?
Thanks for your help.

You try to explicitly list classes (<class>..</class>) in each persistence unit. And use
<exclude-unlisted-classes>true</exclude-unlisted-classes>

Related

JPA specify multiple sql-load-script-source

I need to fill my database on ear startup, so I add javax.persistence.sql-load-script-source tag with reference to the file.
<persistence-unit name="MyPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:/jboss/datasource/mydatasource</jta-data-source>
<jar-file>Entities.jar</jar-file>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="eclipselink.logging.logger" value="org.eclipse.persistence.logging.DefaultSessionLog"/>
<property name="eclipselink.logging.level" value="ALL"/>
<property name="eclipselink.logging.level.sql" value="ALL"/>
<property name="javax.persistence.sql-load-script-source" value="META-INF/defaultdata.sql"/>
<property name="javax.persistence.sql-load-script-source" value="META-INF/insertnations.sql"/>
</properties>
</persistence-unit>
It works, but now i want to use two file because i want to separate "most static" data (like nations and regions of the world) from "per-deploy" data (like some configurations).
Using the tag twice not works.
Is there something wrong?
It is possible to do what i want?
The persistence unit is used in a EAR. I use Wildfly and eclipselink 2.5.2 as persistence provider

Why does the h2 database driver (JPA) not create tables while the postgres does

In a JPA project when using the postgresql driver the tables are auto generated. When i switch to the h2 database driver, I get errors, that the tables are not found. This let me assume, that the tables are not generated.
Postgresql Config
<persistence-unit name="postgresql" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>...</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://127.0.0.1/example"/>
<property name="javax.persistence.jdbc.password" value="example"/>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.user" value="example"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
</properties>
</persistence-unit>
h2 config
<persistence-unit name="OntoJobTestDB" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>...</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
</properties>
</persistence-unit>
It turned out, that the tables could not have been found, because they were never created. An early error caused by a #Converter annotation, which was postgresql specific prevented the creation of the tables.
My advice is to always double check the debug output.

How to create Objects in database if does not exists with JPA?

I have a web application that I use JPA / Hibernate I want to know how to hibernate can generate the non-existent tables from entities.
the persistence file is as follows:
What I can add as property ?
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="BankingApp">
<provider> org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:#localhost:1521:XE"/>
<property name="hibernate.connection.username" value="user"/>
<property name="hibernate.connection.password" value="password"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
</properties>
</persistence-unit>
</persistence>
You can add this property
<property name="hibernate.hbm2ddl.auto" value="update"/>
The possible values for this property are:
validate: Only validates the schema
update: Update the schema
create: Create the schema, override previous data
create-drop: Create the schema and drop the schema at the end of the session
I found the solution, simply add the following property:
<property name="hibernate.hbm2ddl.auto" value="create"/>

Exclude one class from creating a Table in hibernate

I have a persistence unit like this:
<persistence-unit name="persistence Unit"
transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.example.User</class>
<class>com.example.Team</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<!-- JTA stuff -->
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.BTMTransactionManagerLookup" />
</properties>
</persistence-unit>
When the server loads first time, this creates table for User and Team, but i dont want to create a table for Team. Is it possible?
Some settings in the persistence table maybe?
If table Team isn't changed (INSERT or UPDATE) by your application in any way, you could remove write permissions for it in your database system.
Exclude Team class from your persistance.xml Remove following line.
<class>com.example.Team</class>

EclipseLink into OSGI Bundle persistence.xml not found

I'm having some problem with EclipseLink. I'm using GlassFish v3.1 and I'm trying to use EclipseLink for my persistence layer. I followed all tutorials available on the Eclipse wiki without luck. My persistence.xml file cannot be parsed and I receive this error while trying to create the EntityManagerFactory:
org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while processing persistence.xml from URL: bundle://307.1:1/
Here is my persistence.xml located in /WEB-INF/classes/META-INF/:
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="generic">
<class>com.generic.domain.Service</class>
<properties>
<!-- Embedded MySQL Login -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306"/>
<!-- TODO: replace with connection pool -->
<property name="javax.persistence.jdbc.userid" value="root"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="eclipselink.target-database" value="MySQL"/>
<property name="eclipselink.jdbc.read-connections.min" value="1"/>
<property name="eclipselink.jdbc.write-connections.min" value="1"/>
<property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
<!-- Logging Settings -->
<property name="eclipselink.logging.level" value="FINE" />
<property name="eclipselink.logging.thread" value="false" />
<property name="eclipselink.logging.session" value="false" />
<property name="eclipselink.logging.exceptions" value="true" />
<property name="eclipselink.logging.timestamp" value="false"/>
</properties>
</persistence-unit>
</persistence>
I added this line to my MANIFEST.MF:
JPA-PersistenceUnits: generic
I can now confirm that it's a bug in EclipseLink. The work around to your problem is to either get hold of EntityManagerFactory using JNDI lookup or #PersistenceUnit instead of doing Persistence.createEntityManagerFactory().
1) It looks like you are trying to use OSGi/JPA from your WAB. Correct?
2) Can you tell if you have installed any new eclipselink bundles in your system? If so, what are they?
3) Can you provide stack trace?

Categories

Resources