Migrating application context configuration to Spring 3.1 and Hibernate 4.0 - java

I'm having hard time finding migration docs. I was using sping 3.0.5 and hibernate 3.4.
I migrated to the latest release candidates: spring 3.1 and hibernate 4.0
I was able to refactor my classes without problem but the application context for hibernate is giving me problems since I have not see any examples on how to configure it.
Specifically:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>...</list>
</property>
<property name="hibernateProperties">
<props>
...
<prop key="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</prop>
<prop key="hibernate.cache.provider_class">????</prop>
...
</props>
</property>
</bean>
Apparently properties dataSource , mappingResources and hibernateProperties no longer exist and I'm not so sure about what to put in hibernate.connection.provider_class and hibernate.cache.provider_class.
And I keep getting:
Caused by: java.lang.ClassNotFoundException: org.hibernate.engine.FilterDefinition
at application start.

To my knowledge, Spring has no support for Hibernate 4. If it did, I'd expect to see an org.springframework.orm.hibernate4 package in the 3.1.x package list, but it's not there. I don't believe I've seen any mention of it in any release notes or anything, either.
In other words, Spring is working fine, but you're using an incompatible version of Hibernate.

dataSource still exists, based on the JavaDoc for LocalSessionFactoryBean. See the section at the very top; it has an example config with a dataSource property. mappingResources also exists.
The Spring 3.1 reference guide also has an example, with dataSource and mappingResources.
Hibernate 4 does not have a ref guide yet.

Related

How to set ImplicitNamingStrategy.INSTANCE in Hibernate cfg xml (Hibernate4 -> Hibernate5)

New to hibernate and the migration process from Hibernate4 to Hibernate5.
The codebase I'm working with previously used Hibernate4, and we had our naming strategy setup in Hibernate.cfg.xml as such:
<bean id="namingStrategy"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="staticField">
<value>org.hibernate.cfg.ImprovedNamingStrategy.INSTANCE</value>
</property>
</bean>
with the bean then defined in a property tag within our sessionFactory definition. I'm trying to figure out how to do this in Hibernate5.
I read that Hibernate did away with the ImprovedNamingStrategy and went with either PhysicalNamingStrategy or ImplicitNamingStrategy, and that for my purpose I should be using Implicit. I've tried swapping out the strategy names, but that's causing runtime errors as it can't find the class.
<bean id="namingStrategy"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="staticField">
<value>org.hibernate.cfg.ImplicitNamingStrategy.INSTANCE</value>
</property>
</bean>
Any help would be appreciated.

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.

Seam/Hibernate: liquibase before JPA startup

I have a Java EE web application (hibernate3, seam) that I'm using in Weblogic container.
I want to introduce Liquibase for schema migrations.
Currently we use
<property name="hibernate.hbm2ddl.auto" value="update"/>
which we want to drop because it can be dangerous.
I want the migration to automatically happen at deployments, so I'm using the servlet listener integration.
In web.xml, the first listener is:
<listener>
<listener-class>liquibase.integration.servlet.LiquibaseServletListener</listener-class>
</listener>
Sadly, this listener comes into play after the Hibernate initialization and it throws missing table errors (because the schema is empty).
I'm google-ing like a boss for hours and I'm a bit confused now.
Thanks in advance
UPDATE
If I set <property name="hibernate.hbm2ddl.auto" value="none" />, liquibase finishes it's job successfully and the app starts up as expected. If I set validate, it seems like hibernate schema validation takes place before liquibase and it cries because of missing tables.
UPDATE
It seems like Seam initializes Hibernate, but Liquibase listener is listed before SeamListener, so I have no clue on how to enable schema validation and liquibase at the same time...
My understanding is that the LiquibaseServletListener requires the path to change log file which is passed using liquibase.changelog context param. So you already have a change log generated or am I missing something here ?
You can take a look at the liquibase hibernate integration library provided by Liquibase.
This library works with both the classic hibernate configuration (via .cfg and .xml files) as well as JPA configuration via persistence.xml.
AFAIK, generating the changelog and running the change log are two seperate process. Liquibase hibernate integration library helps in generating the change log from the diff of current state of entities in persistence unit and the current database state.
How to determine the order of listeners in web.xml
You should place:
<listener>
<listener-class>liquibase.integration.servlet.LiquibaseServletListener</listener-class>
</listener>
before ORM or framework other related listeners.
I use Spring beans LiquiBase activation to reduce DB authentication data duplication by using already provided datasource bean:
<bean id="liquibase" class="liquibase.integration.spring.SpringLiquibase">
<property name="dataSource" ref="dataSource" />
<property name="changeLog" value="classpath:sql/master.sql" />
<property name="defaultSchema" value="PRODUCT" />
</bean>
To restrict order use depends-on attribute:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
depends-on="liquibase">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="packagesToScan" value="product.domain" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
</props>
</property>
</bean>

datasource configuration error for Spring 2.5.6 & ojdbc6

I'm trying to config datasource in Spring 2.5.6.
My database is oracle 11g and jdbc driver is ojdbc6.
The following is my configuration:
<bean id="databaseConnectionPool" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
<property name="connectionCachingEnabled" value="true"/>
<property name="URL"><value>${jdbc.dburl}</value></property>
<property name="connectionCacheName" value="PSSMST"/>
<property name="user"><value>${jdbc.dbusername}</value></property>
<property name="password"><value>${jdbc.dbpassword}</value></property>
<property name="maxStatements" value="75"/>
<property name="connectionCacheProperties">
<props merge="default">
<prop key="MinLimit">20</prop>
<prop key="MaxLimit">150</prop>
<prop key="InitialLimit">20</prop>
</props>
</property>
</bean>
But when the Tomcat server starts up, I get this message:
Invalid property 'connectionCachingEnabled' of bean class
[oracle.jdbc.pool.OracleDataSource]: Bean property
'connectionCachingEnabled' is not writable or has an invalid setter
method. Does the parameter type of the setter match the return type of
the getter?
That really makes me upset. I checked the OracleDataSource class, of course, the setConnectionCachingEnabled method exists.
Does anybody know how to resolve this?
The probable reason is that you are using an older version of ODBC than intended. Please check lib folder of your application and also check lib folder of Tomcat.

Spring - Switch SchedulerFactoryBean To Be Used

I'm using Spring's SchedulerFactoryBean to run some Quartz jobs within a Spring based java application. At present, this is a single instance application in development, but as soon as we start horizontally scaling this we will want to use a jdbc based JobStore for Quartz so no more than one app will run a given job.
Right now, SchedulerFactoryBean is configured as follows:
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
<property name="taskExecutor" ref="taskExecutor"/>
<property name="triggers">
<list>
<!-- a bunch of triggers here -->
</list>
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
</bean>
and with using a jdbc based JobStore it will look like this
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
<property name="dataSource" ref="mysqlJobDataSource"/>
<property name="taskExecutor" ref="taskExecutor"/>
<property name="triggers">
<list>
<!-- a bunch of triggers here -->
</list>
</property>
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
<!-- and a bunch of other quartz props -->
</props>
</property>
</bean>
Ideally, I'd like to continue using the default RAMJobStore version (the first one) for developers, but use the jdbc version for deployed environments. However, there doesn't seem to be a very good way to switch between the two through something like a property, since the jdbc store involves lots more configuration and the mere existence of the dataSource property on SchedulerFactoryBean means it tries to a JDBC based job store.
Also, Since SchedulerFactoryBean is an initializing bean where the initializing basically starts running all of the jobs, so I can't have both of those beans defined in a config file loaded into the spring context either, which means I'll have parallel jobs running.
I've also read through this answer, but this situtation differs in that I'm dealing with two InitializingBeans that should never be in the same context at the same time.
What would be the simplest way to configure switching between these two configurations of SchedulerFactoryBean?
From Spring 3.1 you can use Spring profiles:
<bean name="schedulerFactoryBean" profile="dev" ...
<bean name="schedulerFactoryBean" profile="prd" ...
Then you can instruct Spring container which profile to use, see How to set active spring 3.1 environment profile via a properites file and not via an env variable or system property and Spring autowire a stubbed service - duplicate bean.
If you can't use 3.1 or profiles, the old-school of solving such issues is to have two context files: schedulerContext-dev.xml and schedulerContext-prd.xml`. Then you can import them selectively:
<import resource="schedulerContext-${some.property}"/>
A better option would be using quartz properties file. As part of your release you can have different files per environment. The context that way is the same for all the environments, the only thing that changes is the configuration file. Using maven profiles you can solve it

Categories