What do values in persistence.xml mean in EJB? - java

I am new to Java and JBoss and JDeveloper. My legacy project has this persistence.xml file:
<persistence-unit name="DoDSRMGR">
<jta-data-source>java:/DoDSRDS</jta-data-source>
<class>dodsr.ManifestsPass1</class>
<class>dodsr.model.ManifestsPass2</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="javax.persistence.jtaDataSource" value="java:/DoDSRDS"/>
</properties>
</persistence-unit>
</persistence>
My questions are what do the values in the file mean and what are they for? Also, where does this file belong in the EAR file META-INF or the JAR file META-INF?
What is the significance of the name="DoDSRMGR" designation, is this the name of the bean when I call from a Java program or is it the application name? Also what is the "java:/DoDSRDS" do?
Is this the way to call the bean from a desktop application:
( DodsrUserSessionEJB) ctx.lookup("/dodsr/"+ejbName+"/remote");

<persistence-unit name="DoDSRMGR"> This line lets you put a name to a persistence unit. You use the persistent unit name when you want to instantiate an EntityManager in this way:
EntityManager eMgr = Persistence.createEntityManagerFactory("Your persistence unit name").createEntityManager();
An EntityManager is the object that helps you select, persist, update and remove your JPA entities from/into the database.
<jta-data-source>java:/DoDSRDS</jta-data-source> This line tells you how you are going to manage the persistence transactions (persist, update and remove entities). If you don't specify this line, every time you want to persist, update or remove an entity from the database, you have to first get a transaction instance and call begin() after you persist/update/remove your entity and after that you call the commit() method.
Since you already have the jta-data-source element in your XML you don't need to manually call the begin() and commit() methods. Your application server manages the transactionality via a transaction resource identified by the value "java:/DoDSRDS"
This XML file can be placed in either META-INF or WEB-INF folder.

Related

Hibernate entity manager looking for tables in different schemas

I am implementing jpa persistence using hiberante-entity manager in a java web project.
I have set following property in in persistence.xml.
<property name="hibernate.hbm2ddl.auto" value="update"/>
I have a schema for each user. For e.g i have a schema for user1 and one for user2.
If the table 'ABC' is present in user1 schema but not in user2 schema & I deploy the application and it uses user2 db credentials, i get the message 'user1.ABC' table found so the 'ABC' table is not created in user2 schema.
When i tried with following property in the persistence.xml file the table is created in the user2 schema.
<property name="hibernate.hbm2ddl.auto" value="create"/>
My question is
why hibernate is searching in another schema i.e user1 if the application is using user2 db credentials? and
I don't want to create the schema every time the server is started so how can i avoid using
the value 'create'.
EDIT: Below is my persistence.xml file
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="XXXXXX" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.axonframework.saga.repository.jpa.SagaEntry</class>
<class>org.axonframework.saga.repository.jpa.AssociationValueEntry</class>
<properties>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Thanks in advance
I am also facing the same issue, and after digging a lot, get to know that the bug is related to the Mysql Connector.
After changing MySql Connector 6.0.5 to 5.1.28 It works fine for me.
I hope It can help you. Cheers
Has the same problem.
After set <property name="hibernate.default_schema" value="MY_SCHEMA"/> the problem has been solved.
Check if you are calling user1 and user2 in your Hibernate Sessionfactory.
If you want to handle several schemas properly then use multi-tenant per schema also if you want to update/create/migrate/handle columns/tables/schemas/databases then use flyway or liquibase
REFERENCES
Multitenancy https://vladmihalcea.com/hibernate-database-schema-multitenancy/
Flyway https://flywaydb.org
Liquibase https://www.liquibase.org
The Hibernate documentation is clear about this, you need to enable multi-tenant operations as described in this answer and this example.
Basically you have to declare multiple persistence units and have each point to a different schema. Each can then use different login credentials as well.
Hibernate documentation link
To summarise:
Define your persistence unit
Define your mapping files per persistence unit
When using JPA add the following:
3. Specifying tenant identifier from SessionFactory
4. Implement a MultiTenantConnectionProvider

ResourceLocal to JTA

I am developing an web application and I have to use JTA which I never used. I started using EntityManager but it seems not to work here. When I use EntityManager I get this message:
Only persistence units with transaction type JTA can be used as a container managed entity manager.
To cut it short, I have this piece of code:
#PersistenceContext(unitName = "zJSF2PU")
private EntityManager em;
em.getTransaction().begin();
//some code
em.getTransaction().commit();
How can I do this without EntityManager?
In your ejb project META-INF/persistence.xml you must have something like:
<?xml version="1.0" encoding="UTF-8"?>
<persistence>
<persistence-unit name="myPersistenceUnitNamePersonalised" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/MySQL</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="eclipselink.logging.level" value="FINE" />
</properties>
</persistence-unit>
</persistence>
And you must declare this in your Application Server (jboss, tomcat, glassfish)
You need to search how to add a data-source and persistence unit in your Application Server...
And that's it... they comunicate thru jndi
Remove transaction-type="RESOURCE_LOCAL" from your persistence.xml.
Remove calls to em.getTransaction(). Inject javax.transaction.UserTransaction (JTA) and use its begin/commit/rollback methods. Alternatively, inject the EM into a stateless EJB instead, and allow the EJB container to automatically manage the transaction.
I finally was able to fix my problem. From my searches it resulted that you can not use EntityManager when you are using JTA within ManagedBeans for example. However it can be used in a stateless bean and then we can inject this Stateless Bean to the ManagedBean and use its methods. The procedure is as follows:
create an EJB (a simple class with #Stateless annotation)
move the method that uses EntityManager to the EJB
inject the EJB into your managed bean (using #EJB annotation) and call the relevant method
For more information refer to this other post: JTA & MySQL

Spring-hibernate jpa and jboss - Saving objects to a second database

Note: Although at first similar, this is not a duplicate of Using Spring, JPA with Hibernate to access multiple databases/datasources configured in Jboss
Dear Stackoverflow,
I had a spring-jpa with hibernate application running on jboss-4.2.1.GA and using a single database.
I now have a second spring-hibernate project bundled up in the same ear file with the project described above but it needs to use a second database. This second hibernate/spring project is set up with the database.properties and hibernate.cfg.xml files.
The two databases details are stored on jboss oracle-ds.xml file:
<datasources>
<local-tx-datasource>
<jndi-name>DefaultDS</jndi-name>
...
</local-tx-datasource>
<local-tx-datasource>
<jndi-name>SecondDS</jndi-name>
...
</local-tx-datasource>
</datasources>
My question is, in the second project, with objects for the second database and not the first one, how can I call sessionFactory for the second database whose details are stored on the oracle-ds.xml instead of using database.properties files?
I have seen an example calling
#Resource(mappedName = "java:SecondDS")
private DataSource secondDS;
...
java.sql.Connection conn = secondDS.getConnection();
If it is that easy to obtain a connection, that is only useful for prepared statements, how can I in get hold of the sessionFactory? Is there a similar approach?
All examples I have seen refer to database.properties and not the jboss ds.xml file.
Thanks in advance
There is several solution, depending on how you bind the data source to a presistance context, Spring way, JPA way or Hibernate way....
Spring
To link spring/hibernate application to JNDI data source, you will need to use JndiObjectFactoryBean
<bean id="serverDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/blah"/>
<property name="proxyInterface" value="javax.sql.DataSource"></property>
</bean>
This way you have a spring bean representing the JNDI data source. You will need to create 2 of them (one for each of you data source). They you need to inject the data source in your spring defined SessionFactory. The same can be use if you use Spring managed JPA entity manager.
JPA
If you are using JPA (session factory is hibernate not jpa...) you can also defined a jndi data source name in the corresponding persistance.xml file.
<persistence-unit name="sample">
<jta-data-source>java:/DefaultDS</jta-data-source>
...
</persistence-unit>
You need to use unitName parameter when injecting the entityManager:
#PersistenceContext(unitName="sample")
Hibernate
For hibernate.cfg.xml file you can specify the JNDI data source with this property
<property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
The database.property should be removed to be sure the jndi data source is used.
These are only example, the final result will depend on how you made your plumbing.

configure Hibernate to use a renamed persistence.xml

We have to rename persistence.xml to fool WebSphere 7 not to use its built-in OpenJPA.
It is pretty easy to do when you use Spring, you just instruct its entity manager factory to use another location for persistence.xml:
<property name="persistenceXmlLocation" value="META-INF/persistence-xxx.xml"/>
But now we want to use plain Hibernate/JPA without Spring, and couldn't find any way to specify the alternate persistence.xml location.
JPA2 spec doesn't say anything about it...
Any clues? Is it possible to instruct Hibernate to use a renamed persistence.xml?
======
It appears that it is NOT POSSIBLE to make Hibernate read a renamed persistence.xml file.
And not necessary in my case.
As far as I know, it's not possible to change the location of the persistence.xml file.
Also take a look at this document: Alternate JPA Providers in WebSphere Application Server, it seems like you should be able to use Hibernate as JPA provider by specifying it in the persistence.xml file, and embedding the required jars in your application.
Make sure your persistence.xml is specifying Hibernate as JPA provider:
<persistence>
<persistence-unit name="myapp">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
You should also be able to achieve this by creating a shared library and using it to configure WebSphere to use an alternative persistence provider.
Here you can find how to do it: Configuring the Java Persistence API (JPA) default persistence provider
EDIT
Given the information in the comments in this answer, it seems the problem can be solved by adding these properties in persistence.xml, as indicated in this post Websphere EntityManagerFactory creation problem:
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.CMTTransactionFactory" />
This same information is also provided in the Alternate JPA Providers in WebSphere Application Server document.
the persistence.xml should exist in a META-INF directory, usually packaged alongside a jar file that contains your entity classes. What I do is I have the entity clases in a seperate project under eclipse, with a META-INF directory that contains the persistence.xml, package this a jar file, and include it in the applications project dependencies (ie. WEB-INF/lib), or, deploy it straight to the app server.

Understanding Persistence.xml in JPA

I am trying to understand the following things:
When I make an EJB project and deploys it to Glassfish do I set up JDBC resources/connection pools at the administrator center of Glassfish or do I add all the different properites for username, password etc in the persistence.xml? I don't understand one bit of that.
I do not understand why we have both JDBC resource and JDBC Connection pool either. What is it and what is the difference between them? Could somebody explain me these things or/and provide some good link about the persistence.xml file and the part around it?
It's better to define a JDBC resource rather than putting the information in the persistence.xml. In this way you are going to take advantage of connection pooling. You are going to define the JNDI name you provided for the JDBC resource in the persistence.xml.
What is it and what is the difference between them
Below I pasted some parts of the Glassfish 3.x help. Check it out. It's really helpful
JDBC connection pool
A JDBC connection pool contains a group of JDBC connections that are created when the connection pool is registered
JDBC resource
A Java DataBase Connectivity (JDBC) resource (data source) provides applications with the means of connecting to a database. Typically, the administrator creates a JDBC resource for each database accessed by the applications deployed in a domain; however, more than one JDBC resource can be created for a database.
Applications get a database connection from a connection pool by looking up a data source on the Java Naming and Directory Interface (JNDI) API tree and then requesting a connection. The connection pool associated with the data source provides the connection to the application.
Think of the data source(JDBC) resource as a factory for a facade of some type of data service(Connection Pool). In this case it implicitly gets a connection from the pool and provides it to your application.
An example persistence.xml:
<?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="WebApplication2PU" transaction-type="JTA">
<jta-data-source>jdbc/sample</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
This line is the JNDI name I gave to my JDBC resourse:
<jta-data-source>jdbc/sample</jta-data-source>
You dont need to define anything related to the database connection in your persistence.xml this way...just the JNDI name of the resource
When you configure a data source in your application server, all you need to set in persistence.xml is the JNDI name of that data source.
I found this in the book that I read to learn Spring and Hibernate. The book name is Professional Java for Web Applications written by Nicholas S. Williams. I think this will be helpful for many people.
Creating the Persistence Configuration:
To use the entities you create, you must define a persistence unit. Doing so is simple. Create a
persistence.xml file not dissimilar from a deployment descriptor, but with far fewer options
to worry about. The root element of a persistence configuration file is <persistence>. This
element may contain one or more <persistence-unit> elements. No other elements are
within <persistence>. <persistence-unit> has two attributes: name specifies the name of
the persistence unit and transaction-type indicates whether this persistence unit uses Java
Transaction API (JTA) transactions or standard local transactions.
You must specify a name, which is how you locate the persistence unit in code. If not specified,
transaction-type defaults to JTA in a Java EE application server and RESOURCE_LOCAL in a Java
SE environment or simple Servlet container. However, to prevent unexpected behavior it’s best to
always set this value explicitly instead of relying on a default value.
<persistence-unit> contains the following inner elements. None of them are required (so
<persistence-unit> may be empty); however, you must specify whichever elements you use in the
following order:
<description> contains a useful description for this persistence unit. Although it makes
reading the persistence file easier, it has no semantic value.
<provider> specifies the fully qualified class name of the javax.persistence.spi
.PersistenceProvider implementation used for this persistence unit. By default, when you
look up the persistence unit, the API will use the first JPA provider on the classpath. You
can include this element to mandate a specific JPA provider.
You can use either <jta-data-source> or <non-jta-data-source> (but not both) to
use a JNDI DataSource resource. You may use <jta-data-source> only if
transaction-type is JTA; likewise you may use <non-jta-data-source> only
if transaction-type is RESOURCE_LOCAL. Specifying a DataSource causes the persistence
unit to use that DataSource for all entity operations.
<mapping-file> specifies the classpath-relative path to an XML mapping file. If you don’t
specify any <mapping-file>, the provider looks for orm.xml. You may specify multiple
<mapping-file> elements to use multiple mapping files.
You can use one or more <jar-file> elements to specify a JAR file or JAR files that the
JPA provider should scan for mapping-annotated entities. Any #Entity, #Embeddable,
#javax.persistence.MappedSuperclass, or #javax.persistence.Converter classes
found are added to the persistence unit.
You can use one or more <class> elements to indicate specific #Entity, #Embeddable,
#MappedSuperclass, or #Converter classes that should be added to the persistence unit.
You must annotate the class or classes with JPA annotations.
Using <exclude-unlisted-classes /> or <exclude-unlisted-classes>true</exclude-unlisted-classes> indicates that the provider should ignore classes not
specified with <jar-file> or <class>. Omitting <exclude-unlisted-classes> or using
<exclude-unlisted-classes>false</exclude-unlisted-classes> causes the JPA
provider to scan the classpath location of the persistence file for JPA-annotated classes. If
persistence.xml is located in a JAR file, that JAR file (and only that JAR file) is scanned
for classes. If persistence.xml is located in a directory-based classpath location (such as /
WEB-INF/classes), that directory (and only that directory) is scanned for classes. Prior to
Hibernate 4.3.0 and Spring Framework 3.2.5, specifying this element with the value false
was incorrectly interpreted as true.
<shared-cache-mode> indicates how entities are cached in the persistence unit (if the JPA
provider supports caching, which is optional). NONE disables caching, whereas ALL enables
caching for all entities. ENABLE_SELECTIVE means that only entities annotated #javax
.persistence.Cacheable or #Cacheable(true) (or marked as cacheable in orm.xml)
are cached. DISABLE_SELECTIVE results in caching of all entities except those annotated
#Cacheable(false) (or marked as non-cacheable in orm.xml). The default value,
UNSPECIFIED, means that the JPA provider decides what the effective default is. Hibernate
ORM defaults to ENABLE_SELECTIVE, but relying on this is not portable.
<validation-mode> indicates if and how Bean Validation should be applied to entities.
NONE means that Bean Validation is not enabled, whereas CALLBACK makes the provider
validate all entities on insert, update, and delete. AUTO has an effective value of CALLBACK
if a Bean Validation provider exists on the classpath and an effective value of NONE if no
Bean Validation provider exists on the classpath. If you enable validation, the JPA provider
configures a new Validator to validate your entities. If you have configured a special
Spring Framework Validator with your custom localized error codes, the JPA provider
ignores it. As such, it’s best to set the validation mode to NONE and use Bean Validation
before your persistence layer is invoked.
<properties> provides a way to specify other JPA properties, including standard JPA
properties (such as JDBC connection string, username, and password, or schema generation
settings) as well as provider-specific properties (such as Hibernate settings). You specify
one or more properties using nested elements, each with a name and value
attribute.
Nicholas S. Williams, Professional Java for Web Applications, (Indianapolis, Indiana: John Wiley & Sons, Inc., 2014), pg 584-585

Categories

Resources