为了克服LazyInitializationException,我决定使用OpenEntityManagerInViewFilter-这是我的实现WebApplicationInitializer的AppInitializer类中的代码:
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.
}
}
这是定义豆的@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用于过滤器?
最佳答案
您正在使用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复制。