hibernate4.LocalSessionFactoryBean cannot be cast to org.hibernate.cfg.Configuration - java

It seems to be a common problem but I am not able to resolve it.
my Spring 3.1.1 configuration is
<bean id="sessionFactoryEditSolution" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="editSolutions-pool"/>
<property name="mappingResources">
<list>
<value>/editsolutions.hibernate.cfg.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
<prop key="net.sf.ehcache.configurationResourceName">/ehcache.xml</prop>
<prop key="hibernate.max_fetch_depth">6</prop>
<prop key="hibernate.default_schema">dbo</prop>
</props>
</property>
</bean>
And this how I am trying to get the configuration object
Configuration editSolutionsConfiguration = `(Configuration)AppContext.getBean("&sessionFactoryEditSolution");`
Initially I have Hibernate 3 for my application but to integrate it with Spring 3.1.1 I have upgraded it to Hibernate 4 .That's why I have to keep hibernate3.jar in my lib folder to support few hibernate 3 specific code lines.

A couple of notes:
you can't work with two versions of hibernate on the classpath. Your old code should be updated
&x returns the factory bean, it doesn't return the produced object. Even without the ampersand, this would return the SessionFactory, rather than Configuration.
with spring you don't need Configuration actually, it is handled behind the scene
we are working with hibernate 3 and spring 3.1. 3.1.1 might be different, but either keep the lower versions of both, or upgrade both (including code)

Related

spring migration 4 to 5; what is causing java.lang.ClassNotFoundException: org.springframework.orm.hibernate4.LocalSessionFactoryBean

I am migrating an old app from Spring 4 to 5. It builds fine with Maven, but when I start the app in jboss 7.1, I get this error:
java.lang.ClassNotFoundException: org.springframework.orm.hibernate4.LocalSessionFactoryBean
Spring 5.3.20
Hibernate 5.3.28.Final
I have been following this guide, https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-5.x
This said Hibernate 5 is required, so I updated that in the pom to 5.3.28.Final
Here is relevant snippet of spring-context.xml:
<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.mycompany.bean.FooService</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
Running with Java 8.
You need to replace org.springframework.orm.hibernate4.LocalSessionFactoryBean with org.springframework.orm.hibernate5.LocalSessionFactoryBean.
The relevant parts of the migration guide are:
Hibernate support has been upgraded to a Hibernate ORM 5.2+ baseline, with a focus on ORM 5.4.x.
This indicates that the minimum version of Hibernate is now Hibernate 5.2.
and
Packages web.view.tiles2 and orm.hibernate3/hibernate4 dropped.
This indicates that the package your XML config is using (org.springframework.orm.hibernate4) no longer exists. Searching for LocalSessionFactoryBean in the Spring Framework 5.3.22 apidoc shows org.springframework.orm.hibernate5.LocalSessionFactoryBean. Its API seems compatible with your XML definition, so changing the class property should be all that you need to change.

Event listeners on hibernate 5

I'm updating my hibernate from version 3 to 5 and I have in my application context I had the following bean
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
p:mappingResources="standard.hbm.xml">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="eventListeners">
<map>
<entry key="merge">
<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</entry>
</map>
</property>
</bean>
The problem is in hibernate 5 I don't have EventListners and also I don't have IdTransferringMergeEventListener. Do I need this? How can I replace?
from api IdTransferringMergeEventListener
Extension of Hibernate's DefaultMergeEventListener, transferring the
ids of newly saved objects to the corresponding original objects (that
are part of the detached object graph passed into the merge method).
So if you don't use this in your project you can skip it. If you need it , you can just copy listener and register one. I think DefaultMergeEventListener has method onMerge(MergeEvent event, Map copiedAlready) that support old IdTransferringMergeEventListener
from IdTransferringMergeEventListener extends org.hibernate.event.def.DefaultMergeEventListener, which has been moved to org.hibernate.event.internal.DefaultMergeEventListener it should be ok.
We intentionally kept Spring's Hibernate 4 support rather minimal, in
order to stay close to the native Hibernate 4 ways of doing things. As
a consequence, we have no plans to reintroduce
IdTransferringMergeEventListener or any of our former LOB user types,
all of which were special-purpose classes to work around issues that
Hibernate should really solve itself - since they have nothing to do
with Spring and caused repeated maintenance headaches on Spring's
side.
You're free to create your own version based on Spring's old
IdTransferringMergeEventListener, of course. However, note that the
way that event listeners can be registered has changed in Hibernate 4:
This is not possible on a per-SessionFactory level anymore, hence
Spring cannot support in its LocalSessionFactoryBean either. Check the
corresponding Hibernate documentation and the corresponding reports on
the Hibernate JIRA for details.

Issues with finding objects queried with HQL or session filter in Hibernate 4 + Spring 4 + JTA

We recently migrated from Hibernate 3.2.3, Spring 3.2.2 to Hibernate 4.3.11 and Spring 4.2.1 on Weblogic 10.3
Now in a transaction when hibernate objects are created and added to a hibernate object's persistent collection and later queried with HQL(using hibernateTemplate) or Hibernate's "Query" feature (in the same transaction and before the end of the transaction), Hibernate fails to find the objects that were added. This worked with Hibernate 3 and Spring 3 before the upgrade, but now fails.
e.g. In Psuedo code, say i have a library class with the following property.
class Library{
private Collection<Books> books;
}
In a transaction, i do the following -
...
Book book1 = new Book();
book1.setAuthor("Patrick Holt");
library.getBooks().add(book1);
and later on in the same transaction, Hibernate's "Query" is used with a Filter to look for books by the author, like so
Session s = hibernateTemplate.getSessionFactory().getCurrentSession();
Query q = s.createFilter(library.getBooks(), "where this.author = :authorName");
q.setParameter("authorName", "Patrick Holt");
List l = q.list();
q.list() in the above example returns 0 results. This would return 1 result before the upgrade. After the upgrade i get 0 results.
I read about some changes in the currentSessionContext in upgrades to Hibernate 4 and Spring 4, but I'm not sure what needs to change in order for the behavior to be just like before the upgrade, without the code having to change.
Out hibernate objects are defined in hbm.xml files and here's my configuration of the session factory.
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">/WEB-INF/ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<!--
Tried adding the following properties, but it didn't work either
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory</prop>-->
</props>
</property>
<property name="dataSource" ref="dataSource"/>
<property name="mappingJarLocations">
<list>
<value>/WEB-INF/lib/app-1.0.jar</value>
</list>
</property>
</bean>
Transaction Manager definition:
<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"/>
The datasource is made available over jndi.
Any ideas on what i need to do to fix this issue?
The issue i was having is exactly as described in Spring Jira Issue SPR-13848. As i understand, it seems like the OpenSessionInViewFilter opens a request scoped session early and there are issues with syncing with a transaction that's started later.
I could not get rid of my OSIV because of the impact that it would cause throughout my application.
However, i found out that hibernate has a property that will accomplish something similar to prevent lazy loading -
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
This solved the issue. Adding this property allowed me to remove the OSIV, and hibernate's AUTO flush mode works as expected in a transaction now. I also used the CMTTransactionFactory. All my hibernate properties:
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">/WEB-INF/ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</prop>
</props>

Performance Issue after upgrading to Hibernate 5.0.2 - Tomcat Server start-up time increased

After upgrading Hibernate version from 4.3.9.Final to 5.0.2.Final, Tomcat Server start-up time has increased.
After debugging, I realized that hibernate takes too much time in adding mapping locations (*.hbm.xml files) in its metadata sources.
I have added mapping location in session factory using following code, and in my project there are around 1000 hbm.xml files.
<bean id="baseSessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.jdbc.fetch_size">300</prop>
<prop key="net.sf.ehcache.configurationResourceName">/ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
</props>
</property>
<property name="dataSource" ref="dataSource" />
<property name="mappingLocations">
<list>
<value>classpath*:com/*/**/*.hbm.xml</value>
</list>
</property>
</bean>
While starting tomcat server, I debugged and fournd that in method
org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet
following for loop takes too much time to add all mapping locations in metadata sources object of configuration class.
if (this.mappingLocations != null) {
// Register given Hibernate mapping definitions, contained in resource files.
for (Resource resource : this.mappingLocations) {
sfb.addInputStream(resource.getInputStream());
}
}
Is there any solution to improve performance here? Anyone noticed such issue after upgrading to Hibernate-5?

Java: DBunitils + Spring: Different Hibernate-Dialect

I currently use spring for depency injection. Hibernate uses a postgres dialect for the normal run, but I want to use HSQL for the DBUnitils Databank-Testing.
My Spring-Configuration contains this:
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="use_outer_join">${hibernate.use_outer_join}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider}</prop>
<prop key="hibernate.connection.pool_size">10</prop>
<prop key="hibernate.jdbc.batch_size">1000</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>de.dbruhn.relations.model.Relation</value>
<value>de.dbruhn.relations.model.RelationData</value>
<value>de.dbruhn.relations.model.RObject</value>
<value>de.dbruhn.relations.model.Type</value>
</list>
</property>
<property name="schemaUpdate" value="${hibernate.schemaUpdate}"/>
</bean>
The fields get replaced by maven resource-filtering.
The Spring-Configruation for DBUnitils contains this:
<bean id="dataSource" class="org.unitils.database.UnitilsDataSourceFactoryBean"/>
</beans>
and so overrides the dataSource from my run configuration with the UnitilsDataSource.
The Problem: I cant run the Tests using Postgres-Dialect against the HSQL-Test-Database because some commands dont work.
The only solution which came to my mind: Switching the resource-filter in maven, but I have to do this by hand (by provining a "-P TEST" on every maven call). So isn't there a possibilty to override the hibernate.dialect?
Thanks!
You normally don't need to specify the dialect at all, Hibernate will figure it out by looking at the underlying datasource. You only need to specify the dialect if you want to force Hibernate to use a specific one.
In your case, you should just be able to remove the dialect property completely, and it should work in postgres and hsql without config modification.
You should possibly look at using the PropertyPlaceHolderConfigurer in spring to change the config. That way you need only supply a different config file for the different environments, the spring xml stays the same.
And you can load the config file like this.

Categories