使用Spring AOP配置Hibernate会话 [英] Configuring Hibernate session with Spring AOP

查看:115
本文介绍了使用Spring AOP配置Hibernate会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用Hibernate 4.3.8作为JPA提供程序的Spring Framework 4应用程序。我想使用Hibernate过滤器,因此我需要启用它们。我想在应用程序中全局执行此操作,我正在尝试使用Spring AOP。这个想法是,我可以编写一个方面,每次创建/获取会话时都会启用过滤器,如 this and 这个问题。



我已经添加了 spring-aop aspectjweaver 依赖到我的项目(使用Maven)。我添加了以下方面。

  @Aspect 
@Component
public class EnableHibernateFilters {
@Pointcut(execution(* org.hibernate.SessionFactory.getCurrentSession(..)))
protected void sessionBeingFetched(){

}

@ AfterReturning(pointcut =sessionBeingFetched(),returns =object)
public void enableFilters(JoinPoint joinPoint,Object object){
System.out.println(!!!启用过滤器!!! ); //从不打印

会话会话=(会话)对象;
session.enableFilter(myFilter);




$ b $ p
$ b我的问题是上述建议( enableFilters )从不被调用;既不打印文字,也不启用我的过滤器。我已经验证了我的方面被检测到,并且AOP在我的项目中工作,将切入点更改为我自己的类中的一个。我也尝试将切入点改为 execution(* org.hibernate.SessionFactory.openSession(..)),但没有结果。



我怀疑这是由于我如何设置Hibernate导致的,因为我没有明确配置 SessionFactory ;相反,我设置了一个 EntityManagerFactory

  @Configuration 
@EnableTransactionManagement
public class PersistenceConfig {
@ Bean
public DataSource dataSource()抛出NamingException {
Context ctx = new InitialContext();
return(DataSource)ctx.lookup(java:comp / env / jdbc / postgres); // JNDI查找
}

@Bean
public EntityManagerFactory entityManagerFactory()抛出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();

返回factory.getObject();

$ b $Be
public JpaTransactionManager transactionManager()throws SQLException,NamingException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(this.entityManagerFactory());

返回transactionManager;


@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();


$ / code $ / pre

基本上我不确定使用哪个切入点以上配置。我曾试着乱用 LocalContainerEntityManagerFactoryBean.setLoadTimeWeaver(),但我无法弄清楚。我不知道是否需要配置。



基本上,我的AOP设置适用于我自己的自定义类。我想或者问题是编织没有配置Hibernate或者其他东西(我对这部分都不熟悉),或者会话不是通过 SessionFactory.getCurrentSession()方法。我尝试通过将切入点改为 execution(* org.hibernate.Hibernate.isInitialized(..))并手动调用<$ c来验证我的建议甚至可以用于Hibernate $ c> Hibernate.isInitialized(null)在我的代码中,但是这也没有触发任何建议,所以这可能是问题。我尝试了建议的内容这篇文章使Hibernate编织,但我不能让它有任何区别。



我也试图将我的切入点设置为<$ c $ (* org.springframework.orm.hibernate4.SessionHolder.getSession(..))执行(* org.springframework.orm.jpa.vendor.HibernateJpaDialect。 getSession(..)),但也没有任何运气。



所以,我不确定下一步该去哪里。我如何从我的建议中获得Hibernate的 Session 对象,这样我就可以启用Hibernate过滤器了?

编辑:
为了防万一,我确实有 @EnableAspectJAutoProxy code>存在于我的配置中:

  @Configuration 
@ComponentScan(basePackages = {...} )
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
// ...
}


解决方案

您的方面类看起来不错。

添加 @Filter @FilterDef
$ b


  • @Filter:将过滤器添加到实体或目标实体。

  • @FilterDef:定义过滤器定义名称和参数,以便在启用过滤器时设置值。




  @Entity 
@Table(name =myTable,schema = mySchema)
@FilterDef(name =myFilter,parameters = @ ParamDef(name =myAttribute,type =integer))
@Filter(name =myFilter,condition = :myAttribute< = attribute)
public class MyEntity实现Serializable {
...
@Column(name =attribute)
private Integer属性;
...

code
$ b $ p
$ b

在您的配置中,过滤器已启用,但没有参数。



测试示例:

 会话。 enableFilter(myFilter)。setParameter(myAttribute,Integer.valueOf(2)); 

当然,您可以在@FilterDef注释中设置所需的参数。



希望它能帮助你。问候,安德烈。


I have a Spring Framework 4 application that uses Hibernate 4.3.8 as the JPA provider. I want to use Hibernate filters, and therefore I need to enable them. I want to do this globally in the application, which I am trying to do with Spring AOP. The idea is that I can write an aspect that enables filters every time a session is created/fetched, like in this and this question.

I have added the spring-aop and aspectjweaver dependencies to my project (using Maven). I have added the following aspect.

@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");
    }
}

My problem is that the above advice (enableFilters) is never invoked; neither the text is printed, nor is my filter enabled. I have verified that my aspect is detected and that AOP works in my project by changing the pointcut to one of my own classes. I have also tried to change the pointcut to execution(* org.hibernate.SessionFactory.openSession(..)), but with no result.

I suspect that this is caused by how I set up Hibernate, because I don't configure a SessionFactory explicitly; rather, I set up an EntityManagerFactory. Here is my configuration.

@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();
    }
}

Basically I am not sure which pointcut to use with the above configuration. I have tried to mess around with LocalContainerEntityManagerFactoryBean.setLoadTimeWeaver(), but I couldn't figure it out. I don't know if I even need to configure that anyways.

Essentially, my AOP setup works for my own custom classes. I guess either the problem is that weaving is not configured with Hibernate or something (I am very unfamiliar with this part of it all) or that the session is not obtained through the SessionFactory.getCurrentSession() method due to my setup. I tried to verify that my advice even worked with Hibernate by changing my pointcut to execution(* org.hibernate.Hibernate.isInitialized(..)) and manually invoking Hibernate.isInitialized(null) in my code, but this did not trigger the advice either, so this might be the problem. I tried what was suggested in this post to enable Hibernate weaving, but I couldn't get it to make any difference.

I also tried to set my pointcut to execution(* org.springframework.orm.hibernate4.SessionHolder.getSession(..)) and execution(* org.springframework.orm.jpa.vendor.HibernateJpaDialect.getSession(..)), but also without any luck.

So, I am not sure where to go next. How can I get a hold of Hibernate's Session object from my advice such that I can enable Hibernate filters? Thank you in advance!

EDIT: Just in case, I do have @EnableAspectJAutoProxy present in my configuration:

@Configuration
@ComponentScan(basePackages = { ... })
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
    // ...
}

解决方案

Your aspect class seems good.

Add @Filter and @FilterDef on your entities :

  • @Filter: Adds filter to an entity or a target entity.
  • @FilterDef: Defines filter definition name and parameters to set values while enabling filter.

Example :

@Entity
@Table(name="myTable", schema="mySchema")
@FilterDef(name="myFilter", parameters=@ParamDef(name="myAttribute", type="integer"))
@Filter(name="myFilter", condition=":myAttribute <= attribute")
public class MyEntity implements Serializable {
    ...
    @Column(name="attribute")
    private Integer attribute;
    ...
}

In your configuration, the filter is enabled, but has no parameters.

Example to test:

session.enableFilter("myFilter").setParameter("myAttribute", Integer.valueOf(2));

Of course, you can set as many parameters as you need in @FilterDef annotation.

Hoping it helps you. Regards, André.

这篇关于使用Spring AOP配置Hibernate会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆