I have a Java application which uses JDBC in order to connect to a Postgres database and JPA to perform operations on it. I wish to use the JTA transaction type, not the local one. For that, I need to specify a data source.
Despite reading this thread, I still have no idea what to actually put in the xml file, as I have no idea how to retrieve the name of my datasource, and/or where and how to define it.
Connection to the database already works without a problem when I use the RESOURCE-LOCAL transaction type. A lot of threads I skimmed through mentioned defining this in a file called context.xml. Does it have to be this file? As no such file has been auto generated for me when creating the JDBC database connection and I would need to create it manually.
In short, if it is possible to get the following file working by adding
<jta-data-source>something</jta-data-source>, please tell me what that something is, or how do I find out. Otherwise, please tell me how and where to define that something.
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1"
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_1.xsd">
<persistence-unit name="BankingPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>banking.Splatka</class>
<class>banking.VlastnikKonta</class>
<class>banking.FyzickaTransakce</class>
<class>banking.Klient</class>
<class>banking.PlatebniKarta</class>
<class>banking.Transakce</class>
<class>banking.Uver</class>
<class>banking.Platba</class>
<class>banking.Konto</class>
<class>banking.BankovniPrevod</class>
<class>DB_control.Transakceprevod</class>
<class>banking.Transakceprevod</class>
<class>banking.TransakcePrevod</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://xxxxxxxxxx"/>
<property name="javax.persistence.jdbc.password" value="xxxx"/>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.user" value="xxxxxxxxxxx"/>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties> </persistence-unit> </persistence>
<jta-data-source>something</jta-data-source>
something will be the jndi name of your datasource in J2EE enviornment.
When you are referring to any datasource you don't need to put below part in you persistence.xml.
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://xxxxxxxxxx"/>
<property name="javax.persistence.jdbc.password" value="xxxx"/>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.user" value="xxxxxxxxxxx"/>
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 am working on a project that uses JDBC through derby.jar, and I am trying to make it usable without the database server running inside NetBeans. I already have a running database (wich is not embedded) and a complete code. Here is my xml that i use.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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_1.xsd">
<persistence-unit name="boltPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>entity.Termek</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/bolt;create=true"/>
<property name="javax.persistence.jdbc.password" value="asd"/>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="javax.persistence.jdbc.user" value="asd"/>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="eclipselink.ddl-generation" value="create-tables"/>
</properties>
</persistence-unit>
</persistence>
Any suggestion for its modification? I tried using EmbeddedDriver instead of ClientDriver, but i got an exception that it cannot be found.
Edit:
I tried putting all required jar files in the classpath and they are all added to the libraries.
Did you try putting the derby jar and other required jars by derby in the classpath of the app?
More instructions here
http://db.apache.org/derby/papers/DerbyTut/embedded_intro.html
Can you edit your question to include stacktrace of errors you get after trying above link
I am involved in writing a project which requires servlet->database connection. I am collaborating with another person who have designed a database using HyperSQL (hsqldb), I am now trying to merge my project with his by adding his code to mine.
Further to my issue though. When I copy the code, it works, usually. I have few methods that use the data from the database and compare them with user input.
When attempting to connect to the database, I would randomly succeed or fail, getting the following error ;
Unable to acquire a connection from driver [null]
I of course initialise a driver ;
Class.forName("org.hsqldb.jdbcDriver").newInstance();
Now, when running my method, it sometimes succeeds, and sometimes fails, here is the XML file for the DB;
<?xml version="1.0" encoding="UTF-8"?>
<!--
Creates both the HyperSQL databases using hibernate. No password or username is set.
-->
<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="monsters" transaction-type="RESOURCE_LOCAL">
<class>databaseManagement.Monster</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.username" value=""/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:monsters"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
<persistence-unit name="users" transaction-type="RESOURCE_LOCAL">
<class>databaseManagement.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.username" value=""/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:users"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Probably an attempt is made to open the database in a readonly directory.
You need to specify a username for both persistence units. The default username is "SA".
The file path of the database that you specify in the URL is relative. It resolves to the execution directory. As you are developing a web application, you need to specify a directory that can be written to.
One way of doing this is by including a variable in the path, such as "jdbc:hsqldb:file:{$directorypath}/monsters" where the directorypath is the name of the web application's data dirctory, as specified in your web.xml file.
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())