bdetweiler bdetweiler - 2 months ago 13x
Java Question

ClassCastException Proxy36 cannot be cast to SessionImplementor after Hibernate/Spring 4 upgrade

EDIT: I am not asking what a ClassCastException is. I am asking what is causing it in DetachedCriteria under this specific configuration of Spring 4/Hibernate 4.

I'm trying to upgrade some legacy code to Spring 4/Hibernate 4 and I've hit a wall, as Google isn't turning up much.

I am trying to run a JUnit test on a very simple Hibernate repository, and it is failing with

java.lang.ClassCastException: com.sun.proxy.$Proxy36 cannot be cast to org.hibernate.engine.spi.SessionImplementor
at org.hibernate.criterion.DetachedCriteria.getExecutableCriteria(

This is happening in Hibernate's

* Get an executable instance of Criteria to actually run the query.
* @param session The session to associate the built Criteria with
* @return The "executable" Criteria
public Criteria getExecutableCriteria(Session session) {
impl.setSession( (SessionImplementor) session );
return impl;

When it tries to set the Session (which attempts to cast it to a SessionImplementor), it throws the ClassCastException.

I suspect this may be an AOP issue, but am not sure where to start looking.

I'm using Spring
, and Hibernate


<bean id="xxxSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

<property name="dataSource" ref="xxxDataSource" />

<property name="mappingResources">

<property name="hibernateProperties">
<prop key="hibernate.dialect">${xxx.hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${xxx.hibernate.showsql}</prop>
<prop key="">${xxx.hibernate.hbm2ddl}</prop>
<prop key="format_sql">${xxx.hibernate.formatsql}</prop>
<prop key="hibernate.query.substitutions">true 1, false 0</prop>

<alias name="xxxSessionFactory" alias="sessionFactory" />


<bean id="xxxTransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />

<tx:advice id="xxxTxAdvice" transaction-manager="xxxDatasourceTransactionManager">
<tx:method name="*" propagation="REQUIRED" />
<!-- all methods begin with save have the transaction -->
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="remove*" propagation="REQUIRED"/>
<tx:method name="inactivate*" propagation="REQUIRED"/>
<tx:method name="complete*" propagation="REQUIRED"/>
<tx:method name="reset*" propagation="REQUIRED"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="flag*" read-only="true"/>
<tx:method name="doWork*" propagation="REQUIRES_NEW" />

<bean id="xxxDatasourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="xxxDataSource" />

<aop:pointcut id="allBusiness" expression="execution(public **Business.*(..))"/>
<aop:advisor advice-ref="xxxTxAdvice" pointcut-ref="allBusiness"/>

public abstract class AbstractHibernateRepository<E extends Entity, S extends Serializable> extends HibernateDaoSupport {
protected E get(final DetachedCriteria detachedCriteria) {
return (E) getHibernateTemplate().execute(new HibernateCallback<E>() {

public E doInHibernate(Session session) {

Criteria criteria = detachedCriteria.getExecutableCriteria(session);
return (E) criteria.uniqueResult();

dur dur

See HibernateTemplate#doExecute

enforceNativeSession - whether to enforce exposure of the native Hibernate Session to callback code

As you can see at GrepCode:

protected Session createSessionProxy(Session session) {
    return (Session) Proxy.newProxyInstance(
    session.getClass().getClassLoader(), new Class<?>[] {Session.class},
    new CloseSuppressingInvocationHandler(session));

the created proxy implements only the interface Session not the interface SessionImplementor.

You have to replace HibernateTemplate#execute with HibernateTemplate#executeWithNativeSession.