How to use TomEE with Hibernate - java

I have created very simple app with persistence context (hibernate as provider) to read some value from database. I use Eclipse with Maven.
First, I get
Caused by: org.apache.openejb.OpenEJBException: java.lang.ClassCastException: org.hibernate.ejb.HibernatePersistence cannot be cast to javax.persistence.spi.PersistenceProvider:
and according to this topic
http://openejb.979440.n4.nabble.com/problem-with-hibernate-persistence-provider-td980429.html
I excluded hibernate-jpa-2.0-api. Now, my dependencies look
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901.jdbc4</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.3.Final</version>
<exclusions>
<exclusion>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
</exclusion>
</exclusions>
</dependency>
Now, I don't know why...
Caused by: java.lang.ClassNotFoundException: org.hibernate.transaction.TransactionManagerLookup
But TransactionManagerLookup is in hibernate-core.
Please, can anybody tell me, how should look pom.xml to use hibernate in TomEE?

1. Copy the required Hibernate .jars to <tomee-home>/lib
According to the documentation ( http://tomee.apache.org/tomee-and-hibernate.html ), the following ones are sufficient and in fact they worked for me:
<tomee-home>/lib/antlr-2.7.7.jar
<tomee-home>/lib/dom4j-1.6.1.jar
<tomee-home>/lib/hibernate-commons-annotations-4.0.2.Final.jar
<tomee-home>/lib/hibernate-core-4.2.21.Final.jar
<tomee-home>/lib/hibernate-entitymanager-4.2.21.Final.jar
<tomee-home>/lib/hibernate-validator-4.3.2.Final.jar
<tomee-home>/lib/javassist-3.18.1-GA.jar
<tomee-home>/lib/jboss-logging-3.1.0.GA.jar
All these .jars are contained in the Hibernate ORM 4.2.x download ( http://hibernate.org/orm/ ), except for the Hibernate Validator, which is a separate download ( http://hibernate.org/validator/ ).
2. Edit your pom.xml
Using the javaee-api maven artifact with a scope of provided you can now use the JPA specification in your project. However, if you have been using some Hibernate specific features, classes or annotations before, you can still refer to Hibernate in your pom.xml to match those dependencies:
<!-- JPA spec (required) -->
<dependencies>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0-4</version>
<scope>provided</scope>
</dependency>
<!-- Hibernate specific features (only if needed) -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.21.Final</version>
<scope>provided</scope>
</dependency>
3. Define your database connection
Edit <tomee-home>/conf/tomee.xml:
<Resource id="myJtaDatabase" type="DataSource">
JdbcDriver com.mysql.jdbc.Driver
JdbcUrl jdbc:mysql://localhost:3306/my_dbname?autoReconnect=true
UserName foo
Password bar
validationQuery = SELECT 1
JtaManaged true
</Resource>
You can also put the above <Resource>...</Resource> definition into WEB-INF/resources.xml and ship it with your application instead:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<!-- Put <Resource> elements here -->
<resources>
4. JTA Datasource
Now that you told TomEE how to establish a connection, define a JTA datasource in /src/main/java/META-INF/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="my_persistence_unit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:openejb/Resource/myJtaDatabase</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<!-- As many hibernate properties as you need, some examples: -->
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<!-- Drop and then re-create the database schema (don't do this in production) -->
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
5. Start using JPA
Obtain an EntityManager in a CDI bean or EJB like this:
#PersistenceContext(unitName = "my_persistence_unit")
private EntityManager em;
Final Notes
Hibernate versions 4.3+
I am using Hibernate 4.2.21 (JPA 2.0, Java EE 6) along with TomEE 1.7.2. Any TomEE 1.7.x, 1.6.x and 1.5.x will work. However, you cannot use Hibernate 4.3+ (JPA 2.1 / Java EE 7), as TomEE 1.7.x and below only support Java EE 6. If you really want to use Java EE 7 features along with TomEE, this blog post might be helpful: http://rmannibucau.wordpress.com/2013/07/19/little-tip-to-help-you-to-test-javaee-7-in-tomee-with-tomee-maven-plugin/
TomEE 1.5.x
TomEE 1.5.x already includes a javassist-<version>.jar, so you don't have to copy one.

Try this:
Add:
<tomee-home>/lib/antlr-2.7.7.jar
<tomee-home>/lib/dom4j-1.6.1.jar
<tomee-home>/lib/ehcache-core-2.5.1.jar
<tomee-home>/lib/ehcache-terracotta-2.5.1.jar
<tomee-home>/lib/hibernate-commons-annotations-4.0.1.Final.jar
<tomee-home>/lib/hibernate-core-4.1.4.Final.jar
<tomee-home>/lib/hibernate-ehcache-4.1.4.Final.jar
<tomee-home>/lib/hibernate-entitymanager-4.1.4.Final.jar
<tomee-home>/lib/hibernate-validator-4.3.0.Final.jar
<tomee-home>/lib/jboss-logging-3.1.0.GA.jar
<tomee-home>/lib/terracotta-toolkit-1.4-runtime-4.1.0.jar
The ehcache jars might be optional, but haven't tried without them.
Remove (optional):
<tomee-home>/lib/asm-3.2.jar
<tomee-home>/lib/bval-core-0.4.jar
<tomee-home>/lib/bval-jsr303-0.4.jar
<tomee-home>/lib/commons-lang-2.6.jar
<tomee-home>/lib/openjpa-2.2.0.jar
<tomee-home>/lib/serp-1.13.1.jar

yes just dropping the hibernate-jpa-2.1-api-1.0.0.Final.jar into the TomEE lib folder worked for me.

Related

Cannot configure hibernate EntityManager configuration with .xml file

I tried to write some code with EntityManager but hibernate was updated to hibernate-core(6.0.0.Final) and with new hibernate 6.0 my old codes doesn't work
There my code:
my pom.xml
enter image description here
my persistence.xml file
<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_1.xsd"
version="2.1">
<persistence-unit name="CRM">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5678/postgres"/>
<property name="hibernate.connection.username" value="postgres"/>
<property name="hibernate.connection.password" value="postgres"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
and my main method
EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("CRM");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(new SuperHero());
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
here result
enter image description here
thanks in advance for your help
It looks as if you are mixing 2 incompatible versions of Hibernate resources:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.0.Final</version>
</dependency>
and:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.6.7.Final</version>
</dependency>
From v6 onwards, the Hibernate libraries have moved from using Java Persistence to Jakarta Persistence. You can read about this larger Java ecosystem change elsewhere Transition from Java EE to Jakarta EE - and also in other SO questions and answers.
By including a Hibernate Entity Manager v5 dependency, your project will still be referring to a Java Persistence library (e.g. via javax.persistence-api-2.2.jar or similar). This means your code may still compile - but, as you see, it will not execute. You will see error messages referring to javax classes, which are no longer supported by the v6 Hibernate Core library.
Furthermore, Hibernate's JPA support has been merged into the hibernate-core module, making the hibernate-entitymanager module obsolete. You can see a note about this by looking at the readme.txt file in your Entity Manager 5.6.7 JAR file:
Hibernate's JPA support has been merged into the hibernate-core module, making this hibernate-entitymanager module obsolete. This module will be removed in Hibernate ORM 6.0.
Recommended steps:
Remove the hibernate-entitymanager dependency from your POM. That will probably trigger a series of compilation errors, because you will no longer have any library support for classes such as javax.persistence.EntityManager.
Update all your javax imports to jakarta imports. So, for example, taking the class from (1) above, that becomes:
import jakarta.persistence.EntityManager;
In your persistence.xml file you will also need to fix any similar references to javax - for example:
<property name="jakarta.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver" />
Final Notes
If you still face issues following the above steps, then you can refer to the official Hibernate ORM 6.0 Migration Guide.

Hibernate C3P0ConnectionProvider not picked up

I am trying to configure C3P0 connection pool for my hibernate application.
I am using below dependencies.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.5.6.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.5.6.Final</version>
</dependency>
I added below configs in my hibernate.cft.xml
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.acquire_increment">5</property>
<property name="hibernate.c3p0.timeout">1800</property>
But I get the warning below:
WARN: HHH000022: c3p0 properties were encountered, but the c3p0 provider class was not found on the classpath; these properties are going to be ignored
If I explicitly specify the provider class like given below, it works.
<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
But the documentation of the above class says it should be picked by default.
A connection provider that uses a C3P0 connection pool. Hibernate will
use this by default if the hibernate.c3p0.* properties are set.
Why is this not class picked up by default? Is it correct to explicitly specify org.hibernate.c3p0.internal.C3P0ConnectionProvider? It looks like org.hibernate.connection.C3P0ConnectionProvider is the class which is picked up by default, and most of the references found in the web are regarding it, but it is not available in the above mentioned maven dependencies.
Remove hibernate. from the property name, it should be:
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>

Integrating Apache Camel with Spring Framework

I'm new to apache camel. I was trying to understand the use of Integrating Spring framework with Apache Camel. I am not comparing Spring vs Apache camel here. I am trying to understand if Dependency Injection is the only use of integrating Spring with camel for a Java Project. Since Camel can take care of a lot of things like routing and also JDBC config that even spring framework can do. In my project we are using Google juice for DI instead of spring. I know that there are other modules like spring security, AOP that could be utilized from spring. But don't you think we can achieve the same using other libraries. So what am i missing here? Is my understanding correct? What are the other uses of integrating spring with apache camel when we can achieve the same DI using google guice and camel.
if your project camel has spring, you can use all features of spring framework, for example if you need Spring JDBC you can declare that dependency and use it in camel. I will give you an example:
In your pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<scope>provided</scope>
</dependency>
In your camel-context.xml
<!-- Datasource -->
<bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource"
id="dataSource">
<property name="driverClass" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="url"
value="${ds.urlString}://${ds.server}:${ds.port};databaseName=${ds.bd}" />
<property name="username" value="${ds.user}" />
<property name="password" value="${ds.password}" />
</bean>
<!-- processors -->
<bean
class="com.mycomapny.Processor"
id="idProcessor" />
As you can see in the example you are injecting dependency, and you can use it in a dao class.
regards

Java Security Policy Preventing Access to Maven Resource Files

I'm currently working on a Maven based project in Eclipse which I want to connect to a database using Hibernate + JPA. I have created a persistence.xml file and placed it in the directory <project>/src/main/resources/META-INF. When I run the application it will throw the very known exception No Persistence provider for EntityManager named
The contents of my persistence.xml:
<?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="NetworkMonDB">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
How I'm initializing this in my application:
public void initializeDatabase(){
final HashMap<String, String> dbConfig = new HashMap<String, String>();
dbConfig.put("javax.persistence.jdbc.url", this.properties.getProperty("database.uri"));
dbConfig.put("javax.persistence.jdbc.user", this.properties.getProperty("database.usr"));
dbConfig.put("javax.persistence.jdbc.password", this.properties.getProperty("database.psw"));
final EntityManagerFactory factory = Persistence.createEntityManagerFactory("NetworkMonDB", dbConfig); //exception thrown at this point.
this.entityManager = factory.createEntityManager();
}
And here are my Maven Dependencies:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.2.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.5</version>
</dependency>
I conducted some further tests (see edits for previous comments on identifying the problem) and it seems the problem comes from my currently used security policy. While I have a security policy file to use when the application is built and packaged in a jar file, I do not have one that will work inside the Eclipse IDE. As soon as I figure out what the best way to configure the security policy I will post it as an answer, unless someone else has an answer.
The problem as described above was caused by a handling of the security policy and security manager. Since this application will eventually read from the hard drive, and work with RMI I need to use a security manager and security policy. However, when working inside the IDE you don't actually need to set a codebase value in the security policy file.
My current solution is to have this as my development area security policy:
grant {
permission java.security.AllPermission;
}
And then the security policy in use when I deploy my application would look like this:
grant codeBase "file:./MyApplication.jar" {
permission java.security.AllPermission;
}
I know that eventually I will need to provide a better more specific security policy for deployment that grants specific permissions to specific file locations and network values, but this should get me going until then.

Spring 3.1, Hibernate 4, SessionFactory

This was working:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
...
but upgrading to the aforementioned versions breaks it. What is the correct method to create a SessionFactory bean with Spring 3.1.Release and Hibernate 4.0.0.FINAL?
The error on deploy is:
nested exception is java.lang.NoClassDefFoundError:
Lorg/hibernate/cache/CacheProvider;
EDIT
Have added my own answer, which fixed it for me.
I think you should use org.springframework.orm.hibernate4.LocalSessionFactoryBean instead of
org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
From LocalSessionFactoryBean javadoc:
NOTE: This variant of LocalSessionFactoryBean requires Hibernate 4.0 or higher. It is similar in role to the same-named class in the orm.hibernate3 package. However, in practice, it is closer to AnnotationSessionFactoryBean since its core purpose is to bootstrap a SessionFactory from annotation scanning.
Hibernate 4 has removed the deprecated CacheProvider-related interfaces and classes in favor of the previously released RegionFactory-related cache interface. You can find the version 4 cache package summary here, the version 3.2 cache package summary here (just before the RegionFactory interface was added) and the version 3.3 cache package summary here (when RegionFactory was first released).
Other than the JavaDoc, you might find the following documentation useful:
Using JBoss Cache as a Hibernate Second Level Cache - Chapter 5. Architecture
Ehcache Hibernate Second-Level Cache
Hibernate 4 - The Second Level Cache
However, based on the Spring 3.1 dependencies Spring 3.1 does not require Hibernate 4 (under the Full Dependencies section, JBoss Hibernate Object-Relational Mapper is at version 3.3.2.GA). If you want to upgrade to Hibernate 4, you'll need to update your cache settings. Otherwise, try using Hibernate 3.3.2 or higher 3.X version instead.
UPDATE: Keep in mind, Hibernate 4 documentation in Spring 3.1 is currently sparse. The Spring Framework Reference Documentation only has the following for Support for Hibernate 4.x:
See Javadoc for classes within the new org.springframework.orm.hibernate4 package
Spring 3.1 introduces the LocalSessionFactoryBuilder, which extends Hibernate's Configuration.
It would seem you should keep an eye out for some other changes if you want to use Hibernate 4.
UPDATE 2: Just noticed this question is a close duplicate of Exception NoClassDefFoundError for CacheProvider.
Use this configuration
hibernate configuration file:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
POM:
<!-- CGLIB -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>${cglib-version}</version>
<scope>runtime</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${org.hibernate-version}</version>
<!-- will come with Hibernate core -->
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
i forgot to include the versions, I am using hibernate version: 4.1.2.Final and spring version: 3.1.1.RELEASE, there is an update of hibernate 4.1.3.Final, not tested but I believe it will work fine.
I had to change a couple of things, here we go :
In my transaction manager set up changed 3 -> 4 :
org.springframework.orm.hibernate4.HibernateTransactionManager;
And my sessionFactory to this (thanks #toxin) :
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
In the case of Hibernate 4.0 or higher, as of Spring 4.0, you should use
org.springframework.orm.hibernate4.LocalSessionFactoryBean
For example:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
...
</bean>
See http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/hibernate4/LocalSessionFactoryBean.html
In the case of Hibernate 5.0/5.1/5.2, as of Spring 4.3, you should better instead use
org.springframework.orm.hibernate5.LocalSessionFactoryBean
(See http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/hibernate5/LocalSessionFactoryBean.html)
Spring 3.1 and Hibernate 4 are not compatible in so many ways. Please refer the following Spring JIRA https://jira.springsource.org/browse/SPR-9365

Categories

Resources