【问题标题】:Injecting a Spring dependency into a JPA EntityListener将 Spring 依赖项注入 JPA EntityListener
【发布时间】:2012-08-22 17:55:31
【问题描述】:

我正在尝试将 Spring 依赖项 注入 JPA EntityListener。这是我的监听类:

@Configurable(autowire = Autowire.BY_TYPE, dependencyCheck = true)
public class PliListener {

    @Autowired
    private EvenementPliRepository evenementPliRepository;

    @PostPersist
    void onPostPersist(Pli pli) {
        EvenementPli ev = new EvenementPli();
        ev.setPli(pli);
        ev.setDateCreation(new Date());
        ev.setType(TypeEvenement.creation);
        ev.setMessage("Création d'un pli");
        System.out.println("evenementPliRepository: " + evenementPliRepository);
        evenementPliRepository.save(ev);
    }


}

这是我的实体类:

@RooJavaBean
@RooToString
@RooJpaActiveRecord
@EntityListeners(PliListener.class)
public class Pli implements Serializable{
...

但是,我的依赖项(即evenementPliRepository始终为空

有人可以帮忙吗?

【问题讨论】:

  • 我也遇到了同样的问题,找到了解决办法,已经在另一个帖子stackoverflow.com/questions/22171221/…
  • 对于任何感兴趣的人,我刚刚尝试了 Spring (5.1.9) Boot (2.1.8) 和 JPA Event Listener 集成,现在它工作得非常好,没有任何黑客或变通方法。我不确定这怎么可能,但也许它也与用于验证的解析器有关。
  • @AndrewTFinnell 我做构造函数注入,它会导致“应用程序上下文中某些 bean 的依赖关系形成一个循环”,我用其他方法不起作用。我很确定 spring boot(org.springframework.boot:spring-boot-starter-data-jpa:2.2.6.RELEASE) 和 hibernate(org.hibernate:hibernate-core:5.4.12.Final) 的版本版本

标签: spring jpa dependency-injection spring-roo entitylisteners


【解决方案1】:

在无状态 bean 上注入依赖项的 hack 是将依赖项定义为“静态”,创建一个 setter 方法以便 Spring 可以注入依赖项(将其分配给静态依赖项)。

将依赖声明为静态。

static private EvenementPliRepository evenementPliRepository;

创建一个方法,以便 Spring 可以注入它。

@Autowired
public void init(EvenementPliRepository evenementPliRepository) 
{
    MyListenerClass.evenementPliRepository = evenementPliRepository;
    logger.info("Initializing with dependency ["+ evenementPliRepository +"]"); 
}

更多详情请访问:http://blog-en.lineofsightnet.com/2012/08/dependency-injection-on-stateless-beans.html

【讨论】:

  • 监听器类必须用@Component(或类似的)注解才能工作
【解决方案2】:

这实际上是一个老问题,但我找到了替代解决方案:

public class MyEntityListener {
    @Autowired
    private ApplicationEventPublisher publisher;

    @PostPersist
    public void postPersist(MyEntity target) {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

        publisher.publishEvent(new OnCreatedEvent<>(this, target));
    }

    @PostUpdate
    public void postUpdate(MyEntity target) {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

        publisher.publishEvent(new OnUpdatedEvent<>(this, target));
    }

    @PostRemove
    public void postDelete(MyEntity target) {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

        publisher.publishEvent(new OnDeletedEvent<>(this, target));
    }
}

可能不是最好的,但比不带 AOP + 编织的静态变量要好。

【讨论】:

  • 在相关实体上添加@EntityListeners(MyEntityListener.class)
  • 试过这个但对我不起作用。请参阅“processInjectionBasedOnCurrentContext()”方法的调试消息:当前 WebApplicationContext 不可用于处理 MyEntityListener:确保此类在 Spring Web 应用程序中构建。继续进行而不注入。
  • 它就像一个魅力!只是有点担心可能的性能问题,因为正如方法名称所说,它会再次处理注入
  • 部分`SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);`不应该一次又一次地执行。最好使用实例布尔值将调用包装到测试中,以检查 DI 是否已被执行。
  • 这是一个很好的解决方案,我所做的唯一更改是在构造函数中调用 processInjectionBasedOnCurrentContext 一次。
【解决方案3】:

我用@Component注解对监听器进行注解,然后创建了一个非静态setter来分配注入的Spring bean,效果很好

我的代码如下:

@Component
public class EntityListener {

    private static MyService service;

    @Autowired
    public void setMyService (MyService service) {
        this.service=service;
    }


    @PreUpdate
    public void onPreUpdate() {

        service.doThings()

    }

    @PrePersist
    public void onPersist() {
       ...
    }


}

【讨论】:

  • 也许 EntityListener.service=service 会比 this.service=service 更好
  • 它对我有用。但你能解释一下吗?我不明白为什么使用静态依赖会起作用。
  • 原因是JPA创建实例时不做依赖注入,后来Spring自己创建实例并设置autowired依赖,即设置静态变量,使所有实例都可以使用MyService实例.
  • 这个解决方案是 hack,导致需要在我的测试中添加 @DirtiesContext。发生这种情况可能是因为侦听器使用的是不同的 MyService 实例,然后是 spring 上下文的其余部分。 EclipseAce 的解决方案运行良好。 (stackoverflow.com/a/60968523/2521628)
【解决方案4】:

从 Spring V5.1(和 Hibernate V5.3)开始,它应该开箱即用,因为 Spring 注册为这些类的提供者。 查看SpringBeanContainer的文档

【讨论】:

  • 在我看来,对于较新的 Hibernate 版本来说,这是最自然的方式,这个答案是最好的并且必须被接受,因为 Hibernate 5.3+ 的使用越来越广泛。 @drenda,请。查看您的 Hibernate 版本,重要的是 Hibernate 版本,而不是 Spring Boot 版本。如果您的 Hibernate 版本被覆盖并且您碰巧使用旧版本,请查看我的答案。
  • 但是解决办法是什么?您的意思是问题上发布的具有@Configurable@Autowired 属性的侦听器应该与Hibernate 5.3+ 一起使用吗?请澄清。
【解决方案5】:

那么这个解决方案呢?

@MappedSuperclass
@EntityListeners(AbstractEntityListener.class)
public abstract class AbstractEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "creation_date")
    private Date creationDate;

    @Column(name = "modification_date")
    private Date modificationDate;

}

然后是监听器...

@Component
public class AbstractEntityListener {

    @Autowired
    private DateTimeService dateTimeService;

    @PreUpdate
    public void preUpdate(AbstractEntity abstractEntity) {
        AutowireHelper.autowire(this, this.dateTimeService);
            abstractEntity.setModificationDate(this.dateTimeService.getCurrentDate());
    }

    @PrePersist
    public void prePersist(AbstractEntity abstractEntity) {
        AutowireHelper.autowire(this, this.dateTimeService);
        Date currentDate = this.dateTimeService.getCurrentDate();
        abstractEntity.setCreationDate(currentDate);
        abstractEntity.setModificationDate(currentDate);
    }
}

还有助手...

    /**
     * Helper class which is able to autowire a specified class. It holds a static reference to the {@link org
     * .springframework.context.ApplicationContext}.
     */
    public final class AutowireHelper implements ApplicationContextAware {

        private static final AutowireHelper INSTANCE = new AutowireHelper();
        private static ApplicationContext applicationContext;

        private AutowireHelper() {
        }

        /**
         * Tries to autowire the specified instance of the class if one of the specified beans which need to be autowired
         * are null.
         *
         * @param classToAutowire the instance of the class which holds @Autowire annotations
         * @param beansToAutowireInClass the beans which have the @Autowire annotation in the specified {#classToAutowire}
         */
        public static void autowire(Object classToAutowire, Object... beansToAutowireInClass) {
            for (Object bean : beansToAutowireInClass) {
                if (bean == null) {
                    applicationContext.getAutowireCapableBeanFactory().autowireBean(classToAutowire);
                }
            }
        }

        @Override
        public void setApplicationContext(final ApplicationContext applicationContext) {
            AutowireHelper.applicationContext = applicationContext;
        }

        /**
         * @return the singleton instance.
         */
        public static AutowireHelper getInstance() {
            return INSTANCE;
        }

    }

为我工作。

来源: http://guylabs.ch/2014/02/22/autowiring-pring-beans-in-hibernate-jpa-entity-listeners/

【讨论】:

  • 如果在 ApplicationContext 本身的初始化中使用了 EntityListener,则此解决方案存在一个陷阱;那么你必须确保AutowireHelper bean 在使用它的代码之前被初始化。
  • 有效,但仅在您在配置 xml 或 Java Spring 配置中注册 AutowireHelper 之后:@Bean public AutowireHelper autowireHelper(){ return AutowireHelper.getInstance(); }
  • @EntityListeners(org.springframework.data.jpa.domain.support.AuditingEntityListener.class) 怎么样
【解决方案6】:

我开始走上使用 AOP 将 spring bean 注入实体侦听器的道路。经过一天半的研究和尝试不同的事情,我发现了这个link,它说:

无法将 Spring 托管 bean 注入 JPA EntityListener 类。这是因为 JPA 侦听器机制应该基于无状态类,因此这些方法实际上是静态的,并且与上下文无关。 ... 再多的 AOP 也救不了你,没有任何东西被注入到代表监听器的“对象”中,因为实现实际上并没有创建实例,而是使用类方法。

此时我重新组合并偶然发现了 EclipseLink DescriptorEventAdapter。使用这些信息,我创建了一个扩展描述符适配器的侦听器类。

public class EntityListener extends DescriptorEventAdapter {
    private String injectedValue;

    public void setInjectedValue(String value){
        this.injectedValue = value;
    }

    @Override
    public void aboutToInsert(DescriptorEvent event) {
       // Do what you need here
    }
}

为了使用该类,我可以在我的实体类上使用@EntityListeners 注释。不幸的是,这种方法不允许 Spring 控制我的侦听器的创建,因此不允许依赖注入。相反,我在我的类中添加了以下“init”函数:

public void init() {
    JpaEntityManager entityManager = null;

    try {
        // Create an entity manager for use in this function
        entityManager = (JpaEntityManager) entityManagerFactory.createEntityManager();
        // Use the entity manager to get a ClassDescriptor for the Entity class
        ClassDescriptor desc = 
            entityManager.getSession().getClassDescriptor(<EntityClass>.class);
        // Add this class as a listener to the class descriptor
        desc.getEventManager().addListener(this);
    } finally {
        if (entityManager != null) {
            // Cleanup the entity manager
            entityManager.close();
        }
    }
}

添加一点 Spring XML 配置

<!-- Define listener object -->
<bean id="entityListener" class="EntityListener " init-method="init">
    <property name="injectedValue" value="Hello World"/>
    <property name="entityManagerFactory" ref="emf"/>
</bean>  

现在我们遇到了这样一种情况,Spring 创建了一个实体监听器,向它注入所需的任何依赖项,然后监听器对象将自己注册到它打算监听的实体类。

我希望这会有所帮助。

【讨论】:

    【解决方案7】:

    我测试了https://guylabs.ch/2014/02/22/autowiring-pring-beans-in-hibernate-jpa-entity-listeners/ 中建议的方法并成功了。不是很干净,但可以完成工作。对我来说稍微修改的 AutowireHelper 类看起来像这样:

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    @Component
    public class AutowireHelper implements ApplicationContextAware {
    
        private static ApplicationContext applicationContext;
    
        private AutowireHelper() {
        }
    
        public static void autowire(Object classToAutowire) {
            AutowireHelper.applicationContext.getAutowireCapableBeanFactory().autowireBean(classToAutowire);
        }
    
        @Override
        public void setApplicationContext(final ApplicationContext applicationContext) {
            AutowireHelper.applicationContext = applicationContext;
        }
    }
    

    然后像这样从实体监听器调用它:

    public class MyEntityAccessListener {
    
        @Autowired
        private MyService myService;
    
    
        @PostLoad
        public void postLoad(Object target) {
    
            AutowireHelper.autowire(this);
    
            myService.doThings();
            ...
        }
    
        public void setMyService(MyService myService) {
            this.myService = myService;
        }
    }
    

    【讨论】:

      【解决方案8】:

      尝试像这样使用ObjectFactory

      @Configurable
      public class YourEntityListener {
          @Autowired
          private ObjectFactory<YourBean> yourBeanProvider;
      
          @PrePersist
          public void beforePersist(Object target) {
             YourBean yourBean = yourBeanProvider.getObject();
             // do somthing with yourBean here
          }
      }
      

      我在 spring-data-jpa 的 org.springframework.data.jpa.domain.support.AuditingEntityListener 中找到了这个解决方案。

      演示:https://github.com/eclipseAce/inject-into-entity-listener

      【讨论】:

      • 我为此写了一个演示,请查看
      • 像魅力一样工作。谢谢。
      • @eclipseAce ,我得到空指针异常,我写的代码完全相同,只是将服务名称更改为我的服务
      【解决方案9】:

      JPA 监听器的问题在于:

      1. 它们不是由 Spring 管理的(所以没有注入)

      2. 它们是(或可能)创建的

      我解决此问题的解决方法:

      1) 使用公共静态LISTENERS 字段创建Listener 类:

      public abstract class Listener {
          // for encapsulation purposes we have private modifiable and public non-modifiable lists
          private static final List<Listener> PRIVATE_LISTENERS = new ArrayList<>();
          public static final List<Listener> LISTENERS = Collections.unmodifiableList(PRIVATE_LISTENERS);
      
          protected Listener() {
              PRIVATE_LISTENERS.add(this);
          }
      }
      

      2) 我们想要添加到Listener.LISTENERS 的所有 JPA 侦听器都必须扩展此类:

      public class MyListener extends Listener {
      
          @PrePersist
          public void onPersist() {
              ...
          }
      
          ...
      }
      

      3) 现在我们可以在 Spring 的 Application Context 准备好之后获取所有侦听器并注入 bean

      @Component
      public class ListenerInjector {
      
          @Autowired
          private ApplicationContext context;
      
          @EventListener(ContextRefreshedEvent.class)
          public void contextRefreshed() {
             Listener.LISTENERS.forEach(listener -> context.getAutowireCapableBeanFactory().autowireBean(listener));
          }
      
      }
      

      【讨论】:

        【解决方案10】:

        我相信这是因为这个监听器 bean 不受 Spring 的控制。 Spring 没有实例化它,Spring 怎么知道如何找到那个 bean 并进行注入?

        我还没有尝试过,但似乎您可以使用带有 Spring 的 Configurable 注释的 AspectJ Weaver 来让 Spring 控制非 Spring 实例化的 bean。

        http://static.springsource.org/spring/docs/3.1.2.RELEASE/spring-framework-reference/html/aop.html#aop-using-aspectj

        【讨论】:

        • 您好,谢谢阿德里安。我已将&lt;context:spring-configured/&gt; 添加到我的配置中。我的 POM 中有 aop*.jars。我不认为我缺少任何东西。 evenementPliRepository 仍然是 null。关于我可能缺少什么的任何其他想法??
        • 代理启动了吗?引用自 ref:Further, in certain environments, this support enables load-time weaving without making any modifications to the application server's launch script that will be needed to add -javaagent:path/to/aspectjweaver.jar or (as we describe later in this section) -javaagent:path/to/org.springframework.instrument-{version}.jar (previously named spring-agent.jar). 但老实说,我之前没有真正尝试过这个功能,可能还有其他我不知道的限制
        • 我要检查一下。我也意识到,因为我使用 Spring Roo,@Configurable 已经由 Roo 设置。让我印象深刻的是,我没有收到有关依赖问题的警告......
        • 你永远不会出错,因为正如我所说,该对象实例不是由 Spring 管理的。拥有那些与 DI 相关的注释毫无意义。没有人会查看这些注释来做任何事情。
        【解决方案11】:

        另一种选择:

        创建服务以使 AplicationContext 可访问:

        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.context.ApplicationContext;
        import org.springframework.stereotype.Service;
        
        import lombok.Setter;
        
        @Service
        class ContextWrapper {
        
            @Setter
            private static ApplicationContext context;
        
            @Autowired
            public ContextWrapper(ApplicationContext ac) {
                setContext(ac);
            }
        
            
        
        }
        

        使用它:

        ...    
        public class AuditListener {
        
            private static final String AUDIT_REPOSITORY = "AuditRepository";
            
            @PrePersist
            public void beforePersist(Object object){
                //TODO:
            }
        
            @PreUpdate
            public void beforeUpdate(Object object){
                //TODO:
            }
            
            @PreRemove
            public void beforeDelete(Object object) {
                getRepo().save(getAuditElement("DEL",object));
            }
            
            private Audit getAuditElement(String Operation,Object object){
        
                Audit audit = new Audit();
                audit.setActor("test");
                Timestamp timestamp = new Timestamp(System.currentTimeMillis());
                audit.setDate(timestamp);
                
                return audit;
            }
        
            private AuditRepository getRepo(){
                return ContextWrapper.getContext().getBean(AUDIT_REPOSITORY, AuditRepository.class);
            }
        }
        

        这个类被创建为来自 jpa 的监听器:

        ...
        @Entity
        @EntityListeners(AuditListener.class)
        @NamedQuery(name="Customer.findAll", query="SELECT c FROM Customer c")
        public class Customer implements Serializable {
            private static final long serialVersionUID = 1L;
        ...
        

        由于监听器不受 Spring 的控制,它无法访问上下文 bean。我已经尝试了多个选项(@Configurable (...)),除了创建一个静态访问上下文的类之外,没有一个有效。已经陷入困境,我认为这是一个优雅的选择。

        【讨论】:

          【解决方案12】:

          从 Hibernate 5.3 版和 Spring 5.1 版(即 Spring Boot 2.1 版)开始,就有了一个简单的解决方案。 无需 hack,无需使用 AOP,无需辅助类,无需显式自动装配,无需 init 块来强制注入。

          你只需要:

          1. 像往常一样将监听器设为@Component 并声明自动装配的bean。
          2. 在 Spring 应用程序中配置 JPA 以使用 Spring 作为 bean 提供程序。

          这里是如何(在 Kotlin 中)...

          1) 实体监听器

          @Component
          class EntityXyzListener(val mySpringBean: MySpringBean) {
          
              @PostLoad
              fun afterLoad(entityXyz: EntityXyz) {
                  // Injected bean is available here. (In my case the bean is a 
                  // domain service that I make available to the entity.)
                  entityXyz.mySpringBean= mySpringBean
              }
          
          }
          

          2) JPA 数据源配置

          在您的应用程序中访问LocalContainerEntityManagerFactoryBean。然后将以下键值对添加到jpaPropertyMapAvailableSettings.BEAN_CONTAINER => 应用程序上下文的 bean 工厂。

          在我的 Spring Boot 应用程序中,我已经有下面的代码来配置数据源(例如找到的样板代码 here)。我只需要添加将BEAN_CONTAINER 属性放入jpaPropertyMap 的代码行。

          @Resource
          lateinit var context: AbstractApplicationContext
          
          @Primary
          @Bean
          @Qualifier("appDatasource")
          @ConfigurationProperties(prefix = "spring.datasource")
          fun myAppDatasource(): DataSource {
              return DataSourceBuilder.create().build()
          }
          
          @Primary
          @Bean(name = ["myAppEntityManagerFactory"])
          fun entityManagerFactoryBean(builder: EntityManagerFactoryBuilder): LocalContainerEntityManagerFactoryBean {
              val localContainerEntityManagerFactoryBean =
                      builder
                              .dataSource(myAppDatasource())
                              .packages("com.mydomain.myapp")
                              .persistenceUnit("myAppPersistenceUnit")
                              .build()
              // the line below does the trick
              localContainerEntityManagerFactoryBean.jpaPropertyMap.put(
                      AvailableSettings.BEAN_CONTAINER, SpringBeanContainer(context.beanFactory))
              return localContainerEntityManagerFactoryBean
          }
          

          【讨论】:

            【解决方案13】:

            在我看来,最自然的方式是干预 EntityListener 的实例化过程。 这种方式在 Hibernate 5.3 之前的版本和 5.3 之后的版本中存在显着差异。

            1) 在 5.3 之前的 Hibernate 版本中 org.hibernate.jpa.event.spi.jpa.ListenerFactory 负责 EntityListener 实例化。如果您提供自己的基于 CDI 的javax.enterprise.inject.spi.BeanManager,则可以拦截此工厂的实例化。 CDI 接口(对于 Spring DI 世界来说是不必要的)冗长,但实现 Spring BeanFactory 支持的 CDI Bean 管理器并不难。

            @Component
            public class SpringCdiBeanManager implements BeanManager {
            
                @Autowired
                private BeanFactory beanFactory;
            
                @Override
                public <T> AnnotatedType<T> createAnnotatedType(Class<T> type) {
                    return new SpringBeanType<T>(beanFactory, type);
                }
            
                @Override
                public <T> InjectionTarget<T> createInjectionTarget(AnnotatedType<T> type) {
                   return (InjectionTarget<T>) type;
                }
                ...
                // have empty implementation for other methods 
            }
            

            类型相关的SpringBeanType&lt;T&gt; 的实现将如下所示:

            public class  SpringBeanType <T> implements AnnotatedType<T>, InjectionTarget<T>{
            
                private BeanFactory beanFactory;
                private Class<T> clazz;
            
                public SpringBeanType(BeanFactory beanFactory, Class<T> clazz) {
                    this.beanFactory = beanFactory;
                    this.clazz = clazz;
                }
            
                @Override
                public T produce(CreationalContext<T> ctx) {
                    return beanFactory.getBean(clazz);
                }
                ...
                // have empty implementation for other methods 
            }
            

            现在,唯一剩下的就是在属性名称javax.persistence.bean.manager 下将BeanManager 的实现注入Hibernate Configuration Settings。可能有很多方法可以做到这一点,我只介绍其中一种:

            @Configuration
            public class HibernateConfig {
            
                @Autowired
                private SpringCdiBeanManager beanManager;
            
                @Bean
                public JpaVendorAdapter jpaVendorAdapter() {
                    HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(){
                        @Override
                        public Map<String, Object> getJpaPropertyMap(){
                            Map<String, Object> jpaPropertyMap = super.getJpaPropertyMap();
                            jpaPropertyMap.put("javax.persistence.bean.manager", beanManager);
                            return jpaPropertyMap;
                        }
                    };
                    // ...
                    return jpaVendorAdapter;
                }
            }
            

            请记住,Spring bean 必须有两件事: a) SpringCdiBeanManager,以便BeanFactory 可以注入/自动连接到它; b)您的 EntityListener 类,以便return beanFactory.getBean(clazz); 行将成功。

            2) 在 Hibernate 5.3 及更高版本中,对于 Spring bean,事情要容易得多,正如 @AdrianShum 非常正确地指出的那样。从 5.3 开始,Hibernate 使用 org.hibernate.resource.beans.container.spi.BeanContainer 概念,并且有其现成的 Spring Beans 实现,org.springframework.orm.hibernate5.SpringBeanContainer。在这种情况下,只需关注其javadoc

            【讨论】:

              【解决方案14】:

              基于 Paulo Merson 的回答,这里是如何使用 JpaBaseConfiguration 设置 SpringBeanContainer 的变体。以下是两个步骤:

              步骤 1:将监听器定义为 Spring 组件。请注意,自动装配通过构造函数注入工作。

              @Component
              public class PliListener {
              
                  private EvenementPliRepository evenementPliRepository;
              
                  public PliListener(EvenementPliRepository repo) {
                      this.evenementPliRepository = repo;
                  }
              
                  @PrePersist
                  public void touchForCreate(Object target) {
                      // ...
                  }
              
                  @PostPersist
                  void onPostPersist(Object target) {
                      // ...
                  }
              }
              

              第 2 步:设置 SpringBeanContainer,这会在侦听器中启用自动装配。 SpringBeanContainer JavaDoc 可能值得一看。

              @Configuration
              public class JpaConfig extends JpaBaseConfiguration {
                  
                  @Autowired
                  private ConfigurableListableBeanFactory beanFactory;
              
                  protected JpaConfig(DataSource dataSource, JpaProperties properties,
                          ObjectProvider<JtaTransactionManager> jtaTransactionManager) {
                      super(dataSource, properties, jtaTransactionManager);
                  }
              
                  @Override
                  protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
                      return new HibernateJpaVendorAdapter();
                  }
              
                  @Override
                  protected Map<String, Object> getVendorProperties() {
                      Map<String, Object> props = new HashMap<>();
              
                      // configure use of SpringBeanContainer
                      props.put(org.hibernate.cfg.AvailableSettings.BEAN_CONTAINER, 
                          new SpringBeanContainer(beanFactory));
                      return props;
                  }
              
              }
              

              【讨论】:

                猜你喜欢
                • 2011-06-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-01-26
                相关资源
                最近更新 更多