6
Forum Spring Projects Data Getting access to hibernate Session within a Hibernate Interceptor If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. Thread: Getting access to hibernate Session within a Hibernate Interceptor Community SpringSource Projects Downloads Documentation Forums Training Blogs User Name Password Log in Remember Me? Register Help What's New? Today's Posts FAQ Calendar Forum Actions Quick Links Advanced Search + Reply to Thread Results 1 to 7 of 7 Thread Tools Display Jun 4th, 2008 10:04 AM Join Date: Location: Posts: Jun 2008 Graz / Austria 3 Getting access to hibernate Session within a Hibernate Interceptor Hi All, I need to get access to a hibernate session object within a custom hibernate interceptor. My interceptor should adjust the underlying OracleConnection to set the sessionTimeZone. The interceptor is regisetred in the persistence.xml file and gets executed as expected. To get access to an entityManager instance I've tried to solve it the same way as I did with my DAO classes. Code: public class SetSessionTimeZoneInterceptor extends EmptyInterceptor { &at;PersistenceContext private EntityManager em; public void setEm(EntityManager em) { this.em = em; } ... /** * retrieves the OracleConnection from the underlying Hibernate Session * &at;return * &at;throws HibernateException * &at;throws SQLException */ private OracleConnection getConnection() throws HibernateException, SQLException { OracleConnection ocon = null; if (em != null) { Session session = ((HibernateEntityManager)em).getSession(); Statement stmt = session.connection().createStatement(); ocon = (OracleConnection)stmt.getConnection(); } else { logger.error("EntityManager is null!"); } return ocon; } But the EntityManager object will never get injected My aplicationContext definition is as follows... Code: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns= .... <!-- bean post-processor for JPA annotations --> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> <bean id="SessionTimeZoneInterceptor" class="com.mycomp.erp.mscom.dal.SetSessionTimeZoneInterceptor"/> ... some more bean definitions ... <!-- enable the configuration of transactional behavior based on annotations --> #1 Junior Member rossmanw Forum Getting access to hibernate Session within a Hib... http://forum.springsource.org/showthread.php?5... 1 of 6 08/01/2011 05:23 PM

Spring Hibernate

Embed Size (px)

Citation preview

Page 1: Spring Hibernate

Forum Spring Projects Data Getting access to hibernate Session within a Hibernate Interceptor

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages,select the forum that you want to visit from the selection below.

Thread: Getting access to hibernate Session within a Hibernate Interceptor

Community SpringSource Projects Downloads Documentation Forums Training Blogs

User Name Password Log in

Remember Me?

RegisterHelp

What's New?

Today's Posts FAQ Calendar Forum Actions Quick Links

Advanced Search

+ Reply to Thread Results 1 to 7 of 7

Thread Tools Display

Jun 4th, 2008 10:04 AM

Join Date:Location:Posts:

Jun 2008Graz / Austria

3

Getting access to hibernate Session within a Hibernate Interceptor

Hi All,

I need to get access to a hibernate session object within a custom hibernate interceptor. My interceptor should adjust the underlying OracleConnection to setthe sessionTimeZone.

The interceptor is regisetred in the persistence.xml file and gets executed as expected.To get access to an entityManager instance I've tried to solve it the same way as I did with my DAO classes.

Code:

public class SetSessionTimeZoneInterceptor extends EmptyInterceptor { &at;PersistenceContext private EntityManager em;

public void setEm(EntityManager em) { this.em = em; } ...

/** * retrieves the OracleConnection from the underlying Hibernate Session * &at;return * &at;throws HibernateException * &at;throws SQLException */ private OracleConnection getConnection() throws HibernateException, SQLException { OracleConnection ocon = null; if (em != null) { Session session = ((HibernateEntityManager)em).getSession(); Statement stmt = session.connection().createStatement(); ocon = (OracleConnection)stmt.getConnection(); } else { logger.error("EntityManager is null!"); } return ocon; }

But the EntityManager object will never get injected

My aplicationContext definition is as follows...

Code:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns= ....

<!-- bean post-processor for JPA annotations --> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

<bean id="SessionTimeZoneInterceptor" class="com.mycomp.erp.mscom.dal.SetSessionTimeZoneInterceptor"/> ... some more bean definitions ... <!-- enable the configuration of transactional behavior based on annotations -->

#1

Junior Memberrossmanw

Forum

Getting access to hibernate Session within a Hib... http://forum.springsource.org/showthread.php?5...

1 of 6 08/01/2011 05:23 PM

Page 2: Spring Hibernate

<tx:annotation-driven transaction-manager="txManager"/> <!-- a PlatformTransactionManager is still required --> <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

<property name="dataSource" ref="myJDBCDataSource"/> <property name="jpaVendorAdapter">

<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><property name="showSql" value="true" /><property name="generateDdl" value="false" /><property name="databasePlatform" value="org.hibernate.dialect.Oracle9Dialect" />

</bean> </property> <property name="persistenceUnitName" value="ComBusPU"/>

<property name="persistenceUnitManager" ref="pum"/> </bean>

The property in my persistence.xml file looks like this:

Code:

<property name="hibernate.ejb.interceptor" value="com.mycomp.erp.mscom.dal.SetSessionTimeZoneInterceptor"/>

Any ideas about how to get the hibernate session object are appreciated.

thanks,Walter

Reply With Quote

Jun 7th, 2008 03:03 AM

Join Date:Posts:

Dec 200719

#2

Junior MemberJeitEmgie

Originally Posted by rossmanw

Hi All,

I need to get access to a hibernate session object within a custom hibernate interceptor. My interceptor should adjust the underlying OracleConnection to set thesessionTimeZone.

The interceptor is regisetred in the persistence.xml file and gets executed as expected.To get access to an entityManager instance I've tried to solve it the same way as I did with my DAO classes.

Code:

public class SetSessionTimeZoneInterceptor extends EmptyInterceptor { &at;PersistenceContext private EntityManager em;

public void setEm(EntityManager em) { this.em = em; } ...

/** * retrieves the OracleConnection from the underlying Hibernate Session * &at;return * &at;throws HibernateException * &at;throws SQLException */ private OracleConnection getConnection() throws HibernateException, SQLException { OracleConnection ocon = null; if (em != null) { Session session = ((HibernateEntityManager)em).getSession(); Statement stmt = session.connection().createStatement(); ocon = (OracleConnection)stmt.getConnection(); } else { logger.error("EntityManager is null!"); } return ocon; }

But the EntityManager object will never get injected

My aplicationContext definition is as follows...

Code:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns= ....

<!-- bean post-processor for JPA annotations --> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

<bean id="SessionTimeZoneInterceptor" class="com.mycomp.erp.mscom.dal.SetSessionTimeZoneInterceptor"/> ... some more bean definitions ... <!-- enable the configuration of transactional behavior based on annotations --> <tx:annotation-driven transaction-manager="txManager"/> <!-- a PlatformTransactionManager is still required --> <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">

Getting access to hibernate Session within a Hib... http://forum.springsource.org/showthread.php?5...

2 of 6 08/01/2011 05:23 PM

Page 3: Spring Hibernate

It seems that your main problem is the entityManager not being injected...but, is not

<context:annotation-config/>

missing from your applicationContext.xml ?

(one you have the entityManager injected, the Hibernate session is the getDelegate()'s result...)

I also wonder if you don't get the Interceptor initialized twiceone by the persistence.xml property, one by the applicationContext.xmland the one being used is not the one being injected...

in which case the problem may the wiring mode (by name/by type) used by Spring…

Last edited by JeitEmgie; Jun 7th, 2008 at 04:14 AM.

<property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

<property name="dataSource" ref="myJDBCDataSource"/> <property name="jpaVendorAdapter">

<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><property name="showSql" value="true" /><property name="generateDdl" value="false" /><property name="databasePlatform" value="org.hibernate.dialect.Oracle9Dialect" />

</bean> </property> <property name="persistenceUnitName" value="ComBusPU"/>

<property name="persistenceUnitManager" ref="pum"/> </bean>

The property in my persistence.xml file looks like this:

Code:

<property name="hibernate.ejb.interceptor" value="com.mycomp.erp.mscom.dal.SetSessionTimeZoneInterceptor"/>

Any ideas about how to get the hibernate session object are appreciated.

thanks,Walter

Reply With Quote

Jun 7th, 2008 06:35 AM

Join Date:Posts:

Dec 200719

One solution (not perfect):

applicationContext:

Code:

<bean id="auditLog" class="YOUR_PACKAGE.YOUR_AUDIT_LOG_HELPER_CLASS"/>

-> diff from original solution: it's not the interceptor class that we use as a bean !

persistence.xml

Code:

<property name="hibernate.ejb.interceptor" value="YOUR_PACKAGE.YOUR_AUDIT_LOG_INTERCEPTOR_CLASS"/>

in YOUR_AUDIT_LOG_HELPER_CLASS

Code:

package YOUR_PACKAGE;

import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;

import YOUR_AUDITLOG_RECORD_ENTITY_CLASS;

import org.hibernate.CallbackException;import org.hibernate.HibernateException;import org.hibernate.Session;

public class YOUR_AUDIT_LOG_HELPER_CLASS {

static protected YOUR_AUDIT_LOG_HELPER_CLASS theAuditLog = null ;

@PersistenceContext(unitName="YOUR_PU_NAME") protected EntityManager itsEntityManager ;

public YOUR_AUDIT_LOG_HELPER_CLASS() { theAuditLog = this ; }

#3

Junior MemberJeitEmgie

Getting access to hibernate Session within a Hib... http://forum.springsource.org/showthread.php?5...

3 of 6 08/01/2011 05:23 PM

Page 4: Spring Hibernate

/** * * @return the entity manager */ protected EntityManager getEntityManager() { return this.itsEntityManager ; }

/**

in YOUR_AUDIT_LOG_INTERCEPTOR_CLASS intercepted methods:

Code:

YOUR_AUDIT_LOG_HELPER_CLASS.logEvent( new YOUR_AUDITLOG_RECORD_ENTITY_CLASS(...) ) ;

and of course test if the entity passed in intercepted calls is not an instanceof YOUR_AUDITLOG_RECORD_ENTITY_CLASS before calling logEvent if you want toavoid infinite recursion…

Reply With Quote

Jun 7th, 2008 08:25 PM

Join Date:Posts:

Jun 200835

"One solution (not perfect):" however is a solution

#4

Memberdreampeppers99

Reply With Quote

Jun 10th, 2008 10:18 AM

Join Date:Location:Posts:

Jun 2008Graz / Austria

3

thank you for posting your solution.I have adopted your suggestion and it works now.

Even tough I'm not really happy with this solution, because the initialization for the session time zone attribute within the Oracle JDBC Connection is done nowmultiple times - each time a statement is prepared.

For anyone else who is inerested in this one solution, I'll poste it below.

In persistence.xml you need to declare your hibernte interceptor:

Code:

<property name="hibernate.ejb.interceptor"value="com.mycomp.erp.mscom.dal.MyHibernateInterceptor" />

Because MyHibernateInterceptor can not be injected with an Instance of EntityManager, a separate Helper Class has to be defined:

Code:

import java.sql.Connection;import java.sql.SQLException;import java.sql.Statement;

import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;

import oracle.jdbc.driver.OracleConnection;

import org.hibernate.HibernateException;import org.hibernate.Session;

/** * @author rossmanw * */public class HibernateInterceptorHelper { protected static HibernateInterceptorHelper theHelper = null; @PersistenceContext(unitName="ComBusPU") protected EntityManager em;

public void setEm(EntityManager em) { this.em = em; }

/** * Constructor */ public HibernateInterceptorHelper() { theHelper = this;

This Helper Class must be declaed in the applicationContext:

#5

Junior Memberrossmanw

Getting access to hibernate Session within a Hib... http://forum.springsource.org/showthread.php?5...

4 of 6 08/01/2011 05:23 PM

Page 5: Spring Hibernate

Code:

<bean id="hibernateInterceptorHelper" class="com.mycomp.erp.mscom.dal.HibernateInterceptorHelper"/>

In the hibenate interceptor the method onPrepareStatement is used to call the static method alterSessionTimeZone of the Helper class.Other methods that could be overridden, e.g. afterTransactionBegin or preFlush can not be used, because either sessoin is not initnialized at this time or thestatement has already been executed.The implemantation of my custom hibernate interceptor is the folowing:

Code:

/** * */package com.mycomp.erp.mscom.dal;

import java.util.TimeZone;

import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.EmptyInterceptor;

/** * @author rossmanw * */public class MyHibernateInterceptor extends EmptyInterceptor { public static final String TIME_ZONE = TimeZone.getDefault().getID(); private static final long serialVersionUID = 1L; private Log logger = LogFactory.getLog(this.getClass()); /* (non-Javadoc) * @see org.hibernate.EmptyInterceptor#onPrepareStatement(java.lang.String) */ @Override public String onPrepareStatement(String sql) { logger .debug("****** in MyHibernateInterceptor.onPrepareStatement() **************"); try { HibernateInterceptorHelper.alterSessionTimeZone(TIME_ZONE);

Hopefully Oracle is going to adopt this problem in a future version of it's jdbc driver implementation...

Reply With Quote

Jul 29th, 2009 02:42 PM

Join Date:Location:Posts:

Dec 2007Boston, MA

34

Great post!! solved my problem!

Another guy posted this http://blog.krecan.net/2009/01/24/sp...ceptor-in-jpa/ to talk about integration of JPA interceptor with Spring. It may be another goodway.

#6

Memberleewill

Reply With Quote

Aug 10th, 2009 06:29 AM

Join Date:Location:Posts:

Jun 2008Graz / Austria

3

another soluton to the original problem of initializing the jdbc connection could be "Wrapping the DataSource", e.g.

Code:

public class MyDataSource implements DataSource {

DataSource delegate = null; public static final String TIME_ZONE = TimeZone.getDefault().getID();

/** * @param delegate the delegate to set */ public void setDelegate(DataSource delegate) { this.delegate = delegate; }

private void doCustomInit(Connection connection) throws SQLException { ... }

/** * @return * @throws SQLException * @see javax.sql.DataSource#getConnection() */ public Connection getConnection() throws SQLException { System.out.println("******************* in MyDataSource.getConnection() ************************"); Connection con = delegate.getConnection(); doCustomInit(con); return con;

#7

Junior Memberrossmanw

Getting access to hibernate Session within a Hib... http://forum.springsource.org/showthread.php?5...

5 of 6 08/01/2011 05:23 PM

Page 6: Spring Hibernate

« Previous Thread | Next Thread »

Contact Us Spring Framework Archive Top

All times are GMT -5. The time now is 05:21 AM.

Powered by vBulletin™ Version 4.1.3Copyright © 2011 vBulletin Solutions, Inc. All rights reserved.

} /**

In your ApplicationConfig you have to define your new DataSource bean. The property delegate has to be the reference to your original DataSource provider.Your new datasource bean must be referenced by the entityManagerFactory bean.

Code:

<bean id="myDataSource" class="com.mycompany.util.MyDataSource"> <property name="delegate" ref="myJNDIDataSource"></property> </bean>... <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="myDataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="true" /> <property name="generateDdl" value="false" /> <property name="databasePlatform" value="org.hibernate.dialect.Oracle9Dialect" /> </bean> </property> </bean>

Regards,Walter

Reply With Quote

+ Reply to Thread Quick Navigation Data Top

You may not post new threadsYou may not post repliesYou may not post attachmentsYou may not edit your posts

Posting Permissions

BB code is OnSmilies are On[IMG] code is OnHTML code is Off

Forum Rules

Getting access to hibernate Session within a Hib... http://forum.springsource.org/showthread.php?5...

6 of 6 08/01/2011 05:23 PM