Spring 3.1, Hibernate 4, SessionFactory - java

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

Related

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>

Log4jConfigurer in Spring 5.0.2

I was using Spring 4.X.X and used the below setup to configure Log4j. Now am upgrading it to Spring 5.0.2 where the Log4jConfigurer class has been removed. How can I do it in Spring 5.0.2?
<bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="org.springframework.util.Log4jConfigurer"/>
<property name="targetMethod" value="initLogging"/>
<property name="arguments">
<list>
<value>classpath:log4j.properties</value>
</list>
</property>
</bean>
The Log4JConfigurer was required for non default Log4j initialisation e.g. if using a custom config file name/location but your config file is located in the default location: classpath:log4j.properties so you can simply remove the Log4jConfigurer declaration and Spring will auto discover your log4j.properties.
There is one possible caveat here; Spring 5 uses Log4j v2 (following Apache's EOL declaration for log4j 1.x) so as long as you are using Log4j v2 then Spring 5 will auto detect it and your log4j.properties file without any need to declare a Log4JConfigurer. If you are not currently using Log4j v2 then I think you'll need to upgrade since Spring 5 does not support the use of Log4j v1.x.

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

Hibernate 4.3.6+ HikariCP Implementation

I am trying to use HikariCP with Hibernate in a maven java ee web app in Netbeans. This is my first time using Hibernate, and I am not using Spring yet as I am not familiar with it but may consider it in the future (please feel free to offer reason why I should adapt it).
In the HikariCP wiki, it mentions that:
As of Hibernate 4.3.6 there is an official ConnectionProvider class
from Hibernate, which should be used instead of the HikariCP
implementation. The class is called
org.hibernate.hikaricp.internal.HikariCPConnectionProvider.
It then goes on to describe the configuration for Hibernate 4.x. It talks about the old ConnectionProvider class there however so I am assuming this section is outdated?
I have added the following dependency to my POM.XML file:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-hikaricp</artifactId>
<version>4.3.8.Final</version>
</dependency>
and with the following properties declared within the tag in hibernate.cfg.xml:
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.provider_class">org.hibernate.hikaricp.internal.HikariCPConnectionProvider</property>
<property name="hibernate.hikari.dataSource.url">jdbc:mysql://localhost/testdb?zeroDateTimeBehavior=convertToNull</property>
<property name="hibernate.hikari.dataSource.user">testuser</property>
<property name="hibernate.hikari.dataSource.password">password</property>
<property name="hibernate.hikari.dataSourceClassName">com.mysql.jdbc.jdbc2.optional.MysqlDataSource</property>
<property name="hibernate.hikari.dataSource.cachePrepStmts">true</property>
<property name="hibernate.hikari.dataSource.prepStmtCacheSize">250</property>
<property name="hibernate.hikari.dataSource.prepStmtCacheSqlLimit">2048</property>
<property name="hibernate.hikari.dataSource.useServerPrepStmts">true</property>
<property name="hibernate.current_session_context_class">thread</property>
I am able to interact with the database as I was before, using the default Hibernate connection pool. Is this all I need to do? Is it now using the HikariCP connection pool? If not what other configuration is required?
If I were to later integrate Spring, how would this affect the HikariCP configuration, or location of the configuration?

How to use TomEE with Hibernate

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.

Categories

Resources