How to define the database path for embedded JTA? - java

How can I manually define the database path for an EclipseLink JTA DB?
<persistence>
<persistence-unit name="myapp" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/myapp</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
</properties>
</persistence-unit>
</persistence>
I'd like to use Squirrel Database tool to inspect the DB, therefore would like to specify the path...
Or is a JTA not ment to have a certain path, but just managed by the container in the background?

You define the JTA-datasource in the container, which is then responsible for placing the datasource at that location for the provider to lookup. The jta-data-source tag just tells the provider what name to use to look it up with.
If you are not in a container, in JPA 2.0 you would use the javax.persistence.jdbc.url property to define the URL. Prior to that you would use vendor specific properties such as "eclipselink.jdbc.url" to define the connection in a java SE environment.

Related

Retrieve information from existing database using JPA

I'm developing a Java Web Project using JPA (EclipseLink) to connect with our databases. I have a persistence unit where I configured the database where my data is going to persisted. The question is that I also have to access another database that is already created and populated with info, and I just want to access one table of this database to retrieve some information. How can I access it using JPA just to retrieve info (neither save nor update anything).
After setting up your entity managers you can just run a native query :
entityManager.createNativeQuery("SELECT ...");
So, you can create another persistent-unit poiting to your other database
<persistence-unit name="read-and-write-database">
...
<properties>
<!-- conection -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/database-write" />
<.../>
</properties>
</persistence-unit>
<persistence-unit name="read-database">
...
<properties>
<!-- conection -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/database-read" />
<.../>
</properties>
</persistence-unit>
And, in a SE environment, you would something like that to create the EntityManager:
EntityManagerFactory readWriteEntityManagerFactory = Persistence.createEntityManagerFactory("read-and-write-database");
EntityManager readWriteEntityManager = readWriteEntityManagerFactory.createEntityManager();
EntityManagerFactory readEntityManagerFactory = Persistence.createEntityManagerFactory("read-database");
EntityManager readEntityManager = readEntityManagerFactory.createEntityManager();
if you are in a container, the PersistenceContext anotation have the unitName field that you can use to define the persistente-unit
Keep in mind that by doing that, you will have two different persistence context. So, changes made in one of then, not gonna be "visiable" to the other one until the persistence of the data.
obs: sorry any typo.
I hope this helps you.
Cheers

how does spring know which connection pool to use?

How does spring know which connection pool to use?
As is known ,you tell the spring framework a persistence-unit name,and annotate the entity manager with #PersistenceContext,and with Persistence.xml configured.Spring does every thing for you.
I am very confused about the spring annotation "#PersitenceContext" above the entityManager field.
My persistence.xml is as below :
<persistence-unit name="hibernate.recommendation_report.jpa">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:#192.168.113.226:11521:BOSS" />
<property name="javax.persistence.jdbc.user" value="xxxx" />
<property name="javax.persistence.jdbc.password" value="xxxx" />
</properties>
</persistence-unit>
My tomcat server and my webapp work well when and after for a short peoriod of time after the starting up of tomcat server.But hours later,the server reports a sqlexception "Connection already closed".
Is this the problem of misusing db connection pool? How do the spring framework choose a c3p0 or DBCP ? How would I specify the connection pool? Or is the tomcat uses the default DBCP as the connection pool?
U can make your tomcat server or other app server provide the JNDI datasource. So that, the your server container's self-contained connection pool can take good care of your the database connection/session.
Tomcat in your case, you specify the JNDI datasource in the $TOMCAT_HOME/conf/context.xml or server.xml:
<Resource name="jdbc/sample" auth="Container"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
username=...
password=...
url=...
driverClassName=...
/>
the type attribute tells the tomcat which connection pool to use.
By default tomcat6 uses DBCP with type of "java.sql.DataSource".
Make sure to use the JNDI reference in your persistence.xml:
<persistence version="2.1" ....>
<persistence-unit name="hibernate.recommendation_report.jpa">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>java:comp/env/jdbc/sample</non-jta-data-source>
</persistence-unit>
</persistence>
Or use spring xml to config the datasource bean to inject into the your entityManagerFactory.Please refer to here.
<jee:jndi-lookup id="dataSource" jndi-name="java:sample"/>
See other JNDI resource attributes available for DBCP.
Note: the "java:comp/env/" prefix in persistence.xml data-source is very import.Without it, Spring will not look for the pool provided by your application server to fetch datasource but just use the attribute to construct a simple datasource.
Note: tomcat8 itself provides a even better pool.If you upgrade to tomcat8.

How Can I insert some data while using JTA Entity Manager

I'm using JBoss 7.1 AS in my application , JPA, Hibernate and MySql DB, I configured everything well and my program is fetching data from db normal. The problem is when I try to insert some data . I found out is the normal that JTA EntityManager cannot use get Transaction , so my question is how Can i insert some data to my db ? Have no idea how Spring works so don't point me to that please, unless it's simple.
my persistance looks like that now:
<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="EngineProject" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/MySqlDS</jta-data-source>
<class>org.itdevelopment.DAO.User</class>
<properties>
<property name="hibernate.show.sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
and my what im trying to do is simple insert some data in the ManagedBean, User class , a a method:
em.getTransaction().begin();
User employee = new User();
employee.setId(23);
employee.setCompany("Coca cola");;
employee.setLogin("James");
em.persist(employee);
em.getTransaction().commit();
as I said it returns:
A JTA EntityManager cannot use getTransaction()
So how Can I insert something ?
Thank you.
M
If you want to use Spring framework than you need to configure Spring container properly. Pleae provide spring configuration and you DAO Class content here.
Here is a link how to do this properly
http://docs.spring.io/spring/docs/3.0.x/reference/orm.html#orm-hibernate
In common case you just need
1.Configure spring and hibernate properly
2.Mark DAO methods as #Transactional with required modifier
Also take a look to Spring Data project that has out of the box solution for Hibernate
http://projects.spring.io/spring-data/

Spring Bootstrap Context for dropping Tables should they exist

I am trying to create an application bootstrap that will drop all the tables in the application if they exist and then intialise them with fresh data.
I have created a Spring Context that loads the datasource context - however I dont know how to override the initialisation of the datasource such that the behaviour can be customised depending on how the datasource is loaded. So.. using Hibernate as my JPA implementation..
If the datasource is loaded from the application - then I would like the schemas to update:
<persistence-unit name="myDB" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
If the datasource is loaded from the bootstrap - then I need to overload this behaviour somehow so that the database is always created from scratch before fresh data is loaded:
<persistence-unit name="myDB" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
The approach I have been taking doesn't work as I would load the datasource using the 'update' setting and then drop the tables if they exist before attempting to load new data. However - the tables no longer exist for writing data !
Thanks in advance
Simon
You can pass JPA properties from Spring configuration instead of persistance.xml and use placeholder that can be configured by PlaceholderConfigurer (possibly system-properties="OVERRIDE"), or Spring profiles (since 3.1) or using Maven filtering:
<util:map id="jpaPropertyMap" key-type="java.lang.String" value-type="java.lang.Object">
<entry key="hibernate.hbm2ddl.auto" value="${database.ddl.mode}" />
</util:map>
<bean id="managementEntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:jpaPropertyMap-ref="jpaPropertyMap" />

JPA Exception: No Persistence provider for EntityManager named MyJPAApplicationPU

I am newbie with JPA. I'm trying to run some sample code using JPA but I get the following exception:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named MyJPAApplicationPU
I put my exception message here,
INFO: Could not find any META-INF/persistence.xml file in the classpath
javax.persistence.PersistenceException: No Persistence provider for EntityManager named MyJPAApplicationPU
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
at com.myJpa.TestJPA.setUp(TestJPA.java:30)
at com.myJpa.TestJPA.main(TestJPA.java:72)
Any help would be appreciated.
Well, the error is self explaining, you need to provide a META-INF/persistence.xml to use JPA. This file is used to define a "persistence unit". From the JPA 1.0 specification:
6.2.1 persistence.xml file
A persistence.xml file defines a
persistence unit. It may be used to
specify managed persistence classes
included in the persistence unit,
object/relational mapping information
for those classes, and other
configuration information for the
persistence unit and for the entity
manager(s) and entity manager factory
for the persistence unit. The
persistence.xml file is located in
the META-INF directory of the root
of the persistence unit. This
information may be defined by
containment or by reference, as
described below.
Here is a sample persistence.xml for a Java SE environment (using Hibernate as JPA provider):
<?xml version="1.0" encoding="UTF-8"?>
<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="MyJPAApplicationPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.mycompany.Foo</class>
<class>com.mycompany.Bar</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.DriverManagerConnectionProvider" />
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:unit-testing-jpa"/>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
Some comments about the above file:
when running in a Java SE environment, you cannot rely on JTA and the transaction type must be RESOURCE_LOCAL (which is actually the default in a Java SE environment but specifying it make it more clear).
when running in a Java SE environment, you cannot use a JDNI data source and the provider will obtain connections directly from the JDBC driver so you must pass the relevant informations to the provider (driver class name, connection url, user, password). With JPA 1.0 the properties used to pass these metadata are provider specific.
To insure the portability of a Java SE application, it is necessary to explicitly list the managed persistence classes that are included in the persistence unit.
For JPA to work, you need META-INF/persistence.xml. I will assume this is a web-app, so this folder has to be in WEB-INF/classes/.
The persistence.xml file would look like this:
<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="MyJPAApplicationPU" transaction-type="RESOURCE_LOCAL">
</persistence-unit>
</persistence>
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<JDBC connection>");
Check the correct JDBC Connection.

Categories

Resources