JPAプロバイダとしてHibernate 4.3.8を使用するSpring Framework 4アプリケーションがあります。私はハイバネートフィルタを使用したいので、それらを有効にする必要があります。私はアプリケーションでこれを全世界的にやりたいと思っています。これはSpring AOPでやろうとしています。私は、セッションが作成/フェッチされるたびに、thisとthisの質問のようなフィルタを有効にするという側面を書くことができます。Spring AOPでHibernateセッションを設定する
Mavenを使用して私のプロジェクトにspring-aop
とaspectjweaver
の依存関係を追加しました。私は次の点を追加しました。
@Aspect
@Component
public class EnableHibernateFilters {
@Pointcut("execution(* org.hibernate.SessionFactory.getCurrentSession(..))")
protected void sessionBeingFetched() {
}
@AfterReturning(pointcut = "sessionBeingFetched()", returning = "object")
public void enableFilters(JoinPoint joinPoint, Object object) {
System.out.println("!!! Enabling filters !!!"); // Never printed
Session session = (Session) object;
session.enableFilter("myFilter");
}
}
私の問題は、上記のアドバイス(enableFilters
)が呼び出されることはありませんということです。テキストは印刷されず、フィルタも有効になりません。私は自分のアスペクトが検出され、AOPが自分のプロジェクトで動作することを確認しました。私のクラスのポイントカットに変更しました。私もexecution(* org.hibernate.SessionFactory.openSession(..))
にポイントカットを変更しようとしましたが、結果はありません。
これは、明示的にSessionFactory
を設定しないため、私はHibernateの設定方法が原因であると思われます。むしろ、私はEntityManagerFactory
を設定しました。ここに私の構成です。
@Configuration
@EnableTransactionManagement
public class PersistenceConfig {
@Bean
public DataSource dataSource() throws NamingException {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/postgres"); // JNDI lookup
}
@Bean
public EntityManagerFactory entityManagerFactory() throws SQLException, NamingException {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
vendorAdapter.setDatabase(Database.POSTGRESQL);
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan(...);
factory.setDataSource(this.dataSource());
factory.afterPropertiesSet();
return factory.getObject();
}
@Bean
public JpaTransactionManager transactionManager() throws SQLException, NamingException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(this.entityManagerFactory());
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
基本的に私は上記の設定でどのポイントカットを使用するのかよく分かりません。私はLocalContainerEntityManagerFactoryBean.setLoadTimeWeaver()
と混乱しようとしましたが、私はそれを理解できませんでした。とにかくそれを設定する必要があるかどうかわかりません。
私のAOP設定は、自分のカスタムクラスで動作します。私は問題は、織り方がHibernateや何かで構成されていないこと(私はこの部分には全く慣れていない)、またはセッションが私の設定のためにSessionFactory.getCurrentSession()
メソッドによって取得されないことです。私は自分のアドバイスが、自分のポイントカットをexecution(* org.hibernate.Hibernate.isInitialized(..))
に変更し、手動でHibernate.isInitialized(null)
を呼び出すことでHibernateと協働していることを検証しようとしましたが、アドバイスを引き起こしませんでした。私はthis post to enable Hibernate weavingで提案されたことを試しましたが、私はそれを得ることができませんでした。
また、私のポイントカットをexecution(* org.springframework.orm.hibernate4.SessionHolder.getSession(..))
とexecution(* org.springframework.orm.jpa.vendor.HibernateJpaDialect.getSession(..))
に設定しようとしましたが、幸運もありませんでした。
私は次にどこに行くのか分かりません。どのようにしてHibernateのSession
オブジェクトを私のアドバイスからホールドして、Hibernateフィルタを有効にすることができますか?前もって感謝します!
EDIT: 念のために、私は私の構成で@EnableAspectJAutoProxy
存在を持っています:
@Configuration
@ComponentScan(basePackages = { ... })
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
// ...
}
'@ComponentScan(" org.hibernate ")'は役に立ちますか? – Ruben
@Rubenいいえ、違いはありません。 – Andy0708
あなたは 'SessioNFactory'をインターセプトしていますが、単純なJPAを使用しています(実装者としてhibernateを使用しています)。明らかに決して進まないでしょう。あなたの設定には 'SessionFactory'がありません。したがって、あなたのアスペクトは何も一致しません。代わりに 'EntityManagerFactory.getEntityManager'のポイントカットを書きます。 –