2017-11-15 5 views
0

- 스프링 4.3, 최대 절전 모드 5 및 MySQL 5.6을 사용하여 웹 응용 프로그램을 만들었습니다.연속적인 서버 요청으로 인해 최대 절전 모드 예외 발생 세션의 안전하지 않은 사용

봄부터 - 1.Spring 핸들러 인터셉터 - 각 요청을 필터링합니다.

2.Spring MVC - REST 웹 리소스를 관리합니다.

3.Spring AOP - ORM 및 세션 연결 관리 - 선언적 접근 방법 (@Transactional)

4.Hibernate와 트랜잭션 매니저로.

응용 프로그램이 서버에 성공적으로 배포되어 로그인 할 수 있습니다.

이제 내 문제에 대해 이야기 해 보겠습니다. - 최대 절전 모드 DAO 계층에서 일부 시간 예외가 발생하면 응용 프로그램에 로그인하여 계속해서 (f5 키를 사용하여) 요청에 응답합니다.

마다처럼 다른 예외 점점 -

  1. org.springframework.orm.hibernate5.HibernateSystemException : HHH000479 : 컬렉션 [dao.domain.WebService.webServicePermissionMaps] 플러시 처리되지 않은(). 이는 세션의 안전하지 않은 사용으로 인한 것일 수 있습니다 (예 : 여러 스레드에서 동시에 사용, 엔티티 라이프 사이클 후크 동안 업데이트).

  2. 내부 서버 오류 같은 컬렉션의 두 표현이 있습니다. dao.domain.WebService.webServicePermissionMaps; .

3 $ {PATTERN} $ {PATTERN}하여 java.lang.NullPointerException : 널 (null) org.hibernate.event.internal.AbstractFlushingEventListener.prepareCollectionFlushes (AbstractFlushingEventListener.java:178)에서 ~ [최대 절전 모드 - 코어 - 5.2.7.Final.jar : 5.2.7.Final]

4. $ {PATTERN} $ {PATTERN} org.springframework.orm.hibernate5.HibernateSystemException : 컬렉션에 대한 공유 참조가 있음 : dao.domain.WebService .webServicePermissionMaps; 중첩 예외는 org.hibernate.HibernateException입니다 : 컬렉션에 대한 공유 참조가 발견되었습니다 : dao.domain.WebService.webServicePermissionMaps.

5. 원인 : java.sql.SQLException : 문을 닫은 후 작업이 허용되지 않습니다. at com.mysql.jdbc.SQLError.createSQLException (SQLError.java:998) ~ [mysql-connector-java-5.1.36.jar : 5.1.36]

다음은 내 코드입니다 : -

@Configuration 
@EnableWebMvc 
@Import({DbConfiguration.class}) 
@ComponentScan(basePackages = "com") 
@PropertySource("classpath:application.properties") 
public class RestConfig extends WebMvcConfigurerAdapter { 
    @Override 
    public void addInterceptors(InterceptorRegistry registry) { 
     registry.addInterceptor(authenticationInterceptor()).excludePathPatterns("/security/authenticate").excludePathPatterns("/security/ssoAuthenticate"); 
     registry.addInterceptor(authorizationInterceptor()).excludePathPatterns("/security/authenticate").excludePathPatterns("/security/ssoAuthenticate"); 
    } 

    @Bean 
    public AuthorizationInterceptor authorizationInterceptor() { 
     return new AuthorizationInterceptor(); 
    } 
} 

DB의 설정 클래스 -

@Configuration 

    @EnableTransactionManagement 

    public class DbConfiguration { 

    @Bean 
    public DataSource dataSource() throws NamingException { 
      return (DataSource) new JndiTemplate().lookup(env.getRequiredProperty("jdbc.url")); 
     } 

@Bean 
@Autowired 
public LocalSessionFactoryBean sessionFactory() throws NamingException { 
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
    sessionFactory.setDataSource(dataSource()); 
    sessionFactory.setPackagesToScan(new String[]{"com.dao"}); 
    sessionFactory.setHibernateProperties(hibProperties()); 
    return sessionFactory; 
} 

@Bean 
@Autowired 
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) { 
    HibernateTransactionManager tm = new HibernateTransactionManager(); 
    tm.setSessionFactory(sessionFactory); 
    return tm; 
} 

private Properties hibProperties() { 
    Properties properties = new Properties(); 
    properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT)); 
    properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, "false"); 
    return properties; 
} 

}

봄 Interceptor-

을 구성 - 313,210

}

-util 클래스

@Service("webServiceUtil") 
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value = "request") 
public class WebServiceUtil { 

@Autowired 
private AuthorizationService authorizationService; 

public boolean isWebServiceAccessbile(Set<String> roles, String basePath, String methodType) 
      throws SysException { 

     try { 
      List<WebService> webservices = authorizationService.getWebService(roles, methodType); 

      List<String> webserviceUrl = new ArrayList<String>(); 
      for (WebService webService : webservices) { 
       webserviceUrl.add(webService.getUrl()); 
      } 

      return webserviceUrl.contains(basePath); 
     } catch (SysException e) { 
      throw e; 
     } 
    } 
} 

- 서비스 클래스

@Service("authorizationService") 
public class AuthorizationServiceImpl implements AuthorizationService { 

@Autowired 
private WebServiceDAO webServiceDAO; 

@Override 
    @Transactional 
    public List<WebService> getWebService(Set<String> roles, String method) throws DataAccessException { 
      return webServiceDAO.getWebServices(roles, method); 
    } 

} 

@Repository 공용 클래스

를 (요청 scope.This 클래스로이 클래스 콩을 원하는 @Transactional을 가지고 있겠지) WebServiceDAOImpl은 BaseDAOImpl을 확장하여 WebServiceDAO {

을 구현합니다.

}

-Base DAO 

public class BaseDAOImpl<T> implements BaseDAO<T> { 

    @Autowired 
    private SessionFactory sessionFactory; 
    private Session session; 
    private Class<T> domainClass; 

    public Session getSessionFromSessionFactory(SessionFactory sessionFactory) { 
     try { 
      session = sessionFactory.getCurrentSession(); 
     } catch (HibernateException he) { 
      log.error("Error in getSessionFromSessionFactory :" + he.getStackTrace()); 
     } 
     return session; 

    } 

    public SessionFactory getSessionFactory() { 
     return sessionFactory; 
    } 

    public void setSessionFactory(SessionFactory sessionFactory) { 
     this.sessionFactory = sessionFactory; 
    } 

    public Session getSession() { 
     return session; 
    } 

    public void setSession(Session session) { 
     this.session = session; 
    } 

} 
+0

코드를 [mcve]로 줄이십시오. – LW001

답변

0

문제가 해결됩니다. 클래스 레벨에서 세션 객체를 만들었 기 때문에 나쁘다. 세션 개체는 스레드간에 공유됩니다.