Java OpenEntityManagerViewFilter-未定义的EntityManagerFactory

Java OpenEntityManagerViewFilter-未定义的EntityManagerFactory,java,spring,spring-mvc,filter,javabeans,Java,Spring,Spring Mvc,Filter,Javabeans,为了克服LazyInitializationException,我决定使用OpenEntityManagerInViewFilter——以下是我的AppInitializer类中实现WebApplicationInitializer的代码: public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer {

为了克服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?

您使用的是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()};
  }

}
公共类AppInitializer扩展AbstractAnnotationConfigDispatcherServletInitializer{
@凌驾
受保护的无效自定义注册(ServletRegistration.Dynamic registration){
setInitParameter(“ThroweExceptionIfNoHandlerFound”、“true”);
}
@凌驾
受保护类[]getRootConfigClasses(){
返回新类[]{PersistenceConfiguration.Class}
}
@凌驾
受保护类[]getServletConfigClasses(){
抛出新类[]{MvcConfiguration.Class};
}
@凌驾
受保护的字符串[]getServletMappings(){
返回新字符串[]{”/“};
}
受保护的筛选器[]getServletFilters(){
返回新筛选器[]{new OpenentityManagerInViewFilter()};
}
}

还要确保在
mvc配置中
没有再次加载
PersistenceConfiguration
类,因为这会导致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()};
  }

}
公共类AppInitializer扩展AbstractAnnotationConfigDispatcherServletInitializer{
@凌驾
受保护的无效自定义注册(ServletRegistration.Dynamic registration){
setInitParameter(“ThroweExceptionIfNoHandlerFound”、“true”);
}
@凌驾
受保护类[]getRootConfigClasses(){
返回新类[]{PersistenceConfiguration.Class}
}
@凌驾
受保护类[]getServletConfigClasses(){
抛出新类[]{MvcConfiguration.Class};
}
@凌驾
受保护的字符串[]getServletMappings(){
返回新字符串[]{”/“};
}
受保护的筛选器[]getServletFilters(){
返回新筛选器[]{new OpenentityManagerInViewFilter()};
}
}


还要确保在
mvc配置中
没有再次加载
PersistenceConfiguration
类,因为这会导致bean重复

@Configuration
类是由
DispatcherServlet
ContextLoaderListener
加载的?我不确定。如何确定?您的
AppInitializer
还应该构造加载配置的
ContextLoaderListener
和/或
DispatcherServlet
。理想情况下,您可以扩展
AbstractAnnotationConfigDispatcherServletInitializer
,并配置加载哪些类(为您保存一些代码行:)。它会同时构造这两个类。我已经发布了完整的代码。你到底为什么有这个玩意儿?你是在扩展一个类,并通过自己实现所有东西来破坏它的功能吗?该类未加载或仅由
DispatcherServlet
加载,这使得
OpenEntityManagerViewFilter
无法检测该类,因为这要求EntityRangerFactory在根上下文中可用。该
@Configuration
类由
DispatcherServlet
加载,或
ContextLoaderListener
?我不确定。如何确定?您的
AppInitializer
还应该构造加载配置的
ContextLoaderListener
和/或
DispatcherServlet
。理想情况下,您可以扩展
AbstractAnnotationConfigDispatcherServletInitializer
,并配置加载哪些类(为您保存一些代码行:)。它会同时构造这两个类。我已经发布了完整的代码。你到底为什么有这个玩意儿?你是在扩展一个类,并通过自己实现所有东西来破坏它的功能吗?类未加载或仅由
DispatcherServlet
加载,这使得
OpenEntityManagerViewFilter无法检测到该类,因为这要求EntityRangerFactory在根上下文中可用。在对未定义的EntityManagerFactory执行该操作后,该问题消失了,但我仍然对它有问题初始化和PersistenceConfiguration无法解析我的属性。因为1,您加载了两次配置,导致两个实体管理器工厂,其中一个打开了与数据库的会话,这是无用的,因为第二个将实际使用。2.您尚未在配置中定义
PropertySourcePlaceHolderConfiguration
,因此您的
@Value
永远不会被替换。我已在WebMVC配置中定义了PropertySourcePlaceHolderConfiguration,并且我的@Value用于正常工作。如何加载配置两次?我现在很困惑;-)一次是通过
ContextLoaderLIstener
,我猜是由于
@组件在
DispatcherServlet
中再次扫描
。CLL中的一个由过滤器使用(无替换值),DS中的一个由其他所有内容使用。理想情况下,您的服务、存储库、基础结构bean(数据源、实体管理器、连接工厂)应该由CLL加载,DS只加载与web相关的内容。非常感谢您的帮助。我将扩展我在这方面的知识,因为我看到有很多事情我可能已经忽略了,因为我刚刚开始了我的Spring冒险;-)我不想再给你添麻烦了,但如果我遇到这样的问题,除了Stack之外,还有什么方法可以联系你吗?再次感谢,您帮了我很大的忙。在使用未定义的EntityManagerFactory解决了这个问题之后,我仍然存在延迟初始化问题,PersistenceConfiguration无法解析我的属性。因为1,您加载了两次配置,导致