OpenEntityManagerInViewFilter - 未定义的EntityManagerFactory

时间:2015-10-11 09:17:01

标签: java spring spring-mvc filter javabeans

为了克服LazyInitializationException,我决定使用OpenEntityManagerInViewFilter - 这是我的AppInitializer类中实现WebApplicationInitializer的代码:

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    registerListener(servletContext);
    registerDipsatcherServlet(servletContext);
    registerOpenEntityManagerInViewFilter(servletContext);
}

private void registerListener(ServletContext servletContext) {
    // Create the 'root' Spring application context
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
    // Manage the lifecycle of the root application context
    servletContext.addListener(new ContextLoaderListener(rootContext));
}

private void registerDipsatcherServlet(ServletContext servletContext) {
    // Create the dispatcher servlet's Spring application context
    AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
    dispatcherServlet.register(MvcConfiguration.class);
    // Register and map the dispatcher servlet
    ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
    customizeRegistration(dispatcher);
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");
}

private void registerOpenEntityManagerInViewFilter(ServletContext servletContext) {
    FilterRegistration.Dynamic registration = servletContext.addFilter("openEntityManagerInView", new OpenEntityManagerInViewFilter());
    registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD), false, "/*");
}

@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
    registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
}

@Override
protected Class<?>[] getRootConfigClasses() {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
protected Class<?>[] getServletConfigClasses() {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
protected String[] getServletMappings() {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

}

这是定义bean的@Configuration类:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager", basePackages = "podraza.piotr.eshopper.repository")
public class PersistenceConfiguration {

    @Autowired
    private JpaVendorAdapter jpaVendorAdapter;

    @Value("${jpa.show-sql:false}")
    private boolean showSql;  

    @Value("${jpa.datasource.url}")
    private String databaseUrl;

    @Value("${jpa.datasource.username}")
    private String username;

    @Value("${jpa.datasource.password}")
    private String password;

    @Value("${jpa.datasource.driverClassName}")
    private String driverClassName;
    /*
    @Value("${jpa.hibernate.ddl-auto}")
    private String hibernateDdlAuto;
    */

    @Bean
    public HibernateJpaVendorAdapter hibernateJpaVendorAdapter() {
        HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
        hibernateJpaVendorAdapter.setShowSql(showSql);
        //hibernateJpaVendorAdapter.getJpaPropertyMap().put("hibernate.hbm2ddl.auto", hibernateDdlAuto);
        hibernateJpaVendorAdapter.setDatabase(Database.POSTGRESQL);
        return hibernateJpaVendorAdapter;
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource(databaseUrl, username, password);
        dataSource.setDriverClassName(driverClassName);
        return dataSource;
    }

    @Bean
    public EntityManager entityManager() {
        return entityManagerFactory().createEntityManager();
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource());
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setPackagesToScan("podraza.piotr.eshopper.entity");
        lef.setPersistenceUnitName("defaultPersistenceUnit");
        lef.afterPropertiesSet();
        return lef.getObject(); 
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager(entityManagerFactory());
    }

}

如何为过滤器指明此bean?

1 个答案:

答案 0 :(得分:0)

你正在使用Spring类,你做的第一件事就是不使用它。将AppInitializer替换为以下内容。

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected void customizeRegistration(ServletRegistration.Dynamic registration) {
      registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
  }

  @Override
  protected Class<?>[] getRootConfigClasses() {
      return new Class[] {PersistenceConfiguration.class}
  }

  @Override
  protected Class<?>[] getServletConfigClasses() {
      throw new Class[] {MvcConfiguration.class};
  }

  @Override
  protected String[] getServletMappings() {
    return new String[] {"/"};
  }

  protected Filter[] getServletFilters() {
    return return new Filter[] {new OpenentityManagerInViewFilter()};
  }

}

另外请确保在MvcConfiguration中您没有再次加载PersistenceConfiguration类,因为这会导致bean重复。