I am new to Java EE and JPA world, and need help with understanding persistence.xml file content. I work with Eclipse IDE, TomEE application server, OpenJPA as persistence provider, and MySQL as database.
Now, lets say I have some Java EE project with annotated entities named A,B and C, and I would like to map these entities to MySQL database named TestDB. I would like for database to be created during deployment, according to entity annotations. On MySQL server I log as "root" user with password "123".
Which properties from persistence.xml correspond to which Java EE environment artifacts (what represents persistence unit, where to specify database name ...)? Is this the correct persistence.xml file content, for situation described above:
<?xml version="1.0" encoding="UTF-8"?>
<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="Test" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost:3306/TestDB" />
<property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver" />
<property name="openjpa.ConnectionUserName" value="root" />
<property name="openjpa.ConnectionPassword" value="123" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
<property name="openjpa.jdbc.DBDictionary" value="mysql" />
<property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO" />
</properties>
</persistence-unit>
</persistence>
What else settings are important for JPA to work properly?
(Appreciate any help)
Above persistence.xml is missing datasource tag:
<jta-data-source>TestDB-jta-DS</jta-data-source>
Then, for Apache TomEE, data source can be defined in [tomee]/conf/tomee.xml configuration file. So, proper datasource definition for above persistence.xml would be:
<Resource id="TestDB-jta-DS" type="DataSource">
JdbcDriver com.mysql.jdbc.Driver
JdbcUrl jdbc:mysql://127.0.0.1:3306/TestDB
UserName root
Password 123
JtaManaged true
DefaultAutoCommit false
</Resource>
Related
My project started with JPA only and it doesn't have Spring. Later, I added Liquibase and I had some issues with the persistence unit name since it is necessary to have one to be able to use EntityManager.
entityManagerFactory = Persistence.createEntityManagerFactory("MyPU");
So, to be able to continue with the tables creation with Liquibase and persisting into the database with JPA, I kept both persistence.xml and liquibase.properties files, despite contaning the same database configuration.
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
version="2.2">
<persistence-unit name="MyPU">
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/jpa_specialist?createDatabaseIfNotExist=true&useTimezone=true&serverTimezone=UTC"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
changeLogFile=src/main/resources/META-INF/database/dbchangelog.xml
url=jdbc:mysql://localhost/jpa_specialist?createDatabaseIfNotExist=true&useTimezone=true&serverTimezone=UTC
username=root
password=root
I've taken a look at liquibase-hibernate and I didn't understand it very well but it seems to be used to generate the diff files, which is not my need at the moment.
Are both files necessary? Is there something I can do to have only one of them?
Liquibase doesn't have a direct way to read the url/username/password information from the presistence.xml file. The liquibase-hibernate extension does add support for diff'ing a database with your java file mapping files, but doesn't change how Liquibase gets the url/username/password.
You said you were not using Spring, but if you are still in a web application, you can use the Liquibase servlet listener to run Liquibase which pulls the connection from a pre-configured datasource. JPA can pull from that same pre-configured datasource instead of re-defining the configuration as well.
Otherwise, unless you want to do a bit of custom Java coding to parse the persistence.xml file and pass it into Liquibase, you do need both files.
To avoid the repetition you could do something like defining build properties in your maven/gradle/whatever setup and have <property name="javax.persistence.jdbc.url" value="${database.url}"/>in your persistence.xml source file, and url: ${database.url} in your liquibase.properties file.
I have gone though https://www.playframework.com/documentation/2.5.x/JavaJPA
But it doesn't feel like a stardard way. I would like fill my jdbc connection in persistence.xml instead of application.conf
like this
<?xml version="1.0" encoding="UTF-8" ?>
<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_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="TestPersistence"
transaction-type="RESOURCE_LOCAL">
<class>com.example.pojo.Employee</class>
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<non-jta-data-source>DefaultDS</non-jta-data-source>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/jpadb" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password"
value="mukesh" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
</properties>
</persistence-unit>
</persistence>
instead of filling the jdbc connection in application.conf like
db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost:3306/jpadb"
db.default.user=root
db.default.password="mukesh"
db.default.jndiName=DefaultDS
jpa.default=TestPersistence
Also if there is no other way to get jdbc connection in persistence.xml how can we define more than one jdbc connection in application.conf. like if i have a mysql for users and oracle db for posts.
NOTE: the source code posted are just dummy copied from public domain to show the briefly problem.
You don't have to use Play's DB module. You can have your own module defined, and load your database connection and run it in isolation.
I would check out https://github.com/playframework/play-isolated-slick as an example -- here the UserDAO is bound through to SlickDAO in the Play module:
https://github.com/playframework/play-isolated-slick/blob/master/modules/play/app/Module.scala#L19
and the database provider is provided:
https://github.com/playframework/play-isolated-slick/blob/master/modules/play/app/Module.scala#L27
but you don't have to use Database.forConfig("myapp.database") -- you can define any config you feel like.
I have a standalone java application, which uses JPA for its persistence.
Right now I have a persistence.xml in META-INF.My application is currently in development.
My question is that if I move from development to the next envirnoment, say QA. I have to modify the persistence.xml and rebuild the jar. Is this the right way to go about it ?
If not,if I move the connection properties to a different file, where should this file be placed?
<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_2_0.xsd" version="2.0">
<persistence-unit name="pu1" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>ClassA</class>
<class>ClassB</class>
<class>ClassC</class>
<class>ClassD</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9Dialect" />
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.connection.username" value="username" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.connection.url"
value="url" />
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.archive.autodetection" value="class" />
</properties>
</persistence-unit>
</persistence>
Thanks in advance !
That's a good question. Normally, you put all these environment settings in an external file, say application.properties, and pass the location to it to the JVM when you start your application (e.g. -Dconfig.location=/conf/)
Then you should find a way to get the externalized properties into your EntityManagerFactory. You can't do that in persistence.xml, you can only hard-code things there. But you can do it when creating the entity manager factory by passing vendor properties.
If using a framework like spring, for example, this is easier to do, as spring provides a factory bean for the entity manager. Otherwise you should handle it yourself. Here's the relevant bit from spring:
provider.createEntityManagerFactory(persistenceUnitInfo, getJpaPropertyMap())
Hey I'm getting a persistence provide not found exception the code for my persistence.xml is
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="GWTSales"
transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.jeroennouws.sales.beans.Branch</class>
<class>com.jeroennouws.sales.beans.Customer</class>
<class>com.jeroennouws.sales.beans.Employee</class>
<class>com.jeroennouws.sales.beans.Product</class>
<class>com.jeroennouws.sales.beans.Purchase</class>
<class>com.jeroennouws.sales.beans.PurchaseDetail</class>
<class>com.jeroennouws.sales.beans.PurchaseDetailPK</class>
<class>com.jeroennouws.sales.beans.Sale</class>
<class>com.jeroennouws.sales.beans.SalesDesk</class>
<class>com.jeroennouws.sales.beans.SalesDetail</class>
<class>com.jeroennouws.sales.beans.SalesDetailPK</class>
<class>com.jeroennouws.sales.beans.Stock</class>
<class>com.jeroennouws.sales.beans.Supplier</class>
<class>com.jeroennouws.sales.beans.User</class>
<properties>
<property name="eclipselink.jdbc.password" value="" />
<property name="eclipselink.jdbc.user" value="root" />
<property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306/sales" />
<property name="eclipselink.logging.level" value="INFO" />
</properties>
</persistence-unit>
</persistence>
and the code that generates this exception is
public BranchJpaController() {
emf = Persistence.createEntityManagerFactory("GWTSales");
}
I have tried all different kinds of things by now, eclipselink jar file is in my WEB-INF/lib folder and my persistence.xml file is in my src/META-INF folder.
Does this has something to do with the GWT Jetty server in the eclipse plugin or am I missing something?
Check if the MySQL JDBC Driver is in your WEB-INF/lib folder.
I hope it helps.
I am using Weblogic 11.
After initial deployment of all JMS configurations, JDBC configuration (from XADS-jdbc.xml) and ears everything works properly.
But after weblogic restart application fails to initialize with error
Caused By: java.lang.UnsupportedOperationException: The user must supply a JDBC connection
at org.hibernate.connection.UserSuppliedConnectionProvider.getConnection(UserSuppliedConnectionProvider.java:54)
at org.hibernate.tool.hbm2ddl.SuppliedConnectionProviderConnectionHelper.prepare(SuppliedConnectionProviderConnectionHelper.java:51)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:130)
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)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:132)...
According to log JDBC and EAR start their initialization simultaniously. So when EAR tries to validate DB scheme JDBC configuration initialization is not completed yet.
What could fix such situation?
Are there any weblogic configurations using which deployment items initialization could be ordered?
Thanks in Advance.
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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="TestDSPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/testN/test/TestXADS</jta-data-source>
<mapping-file>META-INF/orm.xml</mapping-file>
<properties>
<!-- <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect"/> -->
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<!-- <property name="hibernate.cache.use_query_cache" value="true"/> -->
<property name="hibernate.cache.region_prefix" value="hibernate.test"/>
<property name="hibernate.jdbc.use_streams_for_binary" value="true"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WeblogicTransactionManagerLookup"/>
<property name="show_sql" value="true"/>
<property name="hibernate.query.factory_class" value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory"/>
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
</persistence-unit>
Did you try creating the JDBC connections through admin console? If not, please try creating the data source through admin console. Once done, open your config.xml, you should see something like below:
<jdbc-system-resource>
<name>TestXADS</name>
<target>AdminServer</target>
<descriptor-file-name>jdbc/TestXADS-jdbc.xml</descriptor-file-name>
</jdbc-system-resource>
Please Note: The outer node should be <jdbc-system-resource >
I would double check WebLogic is deploying resources in the default order as stated in docs.