2016-05-25 6 views
0

まあ、私は私の保護のために春のWeb MVCを使用して、私のWebAppInitializerで構成された2つのディスパッチャ持っている:通常のWebアプリケーションの春WSインターセプタ - カントセッションを取得

@Override 
    public void onStartup(ServletContext container) { 
     // Create the 'root' Spring application context 
     AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); 
     rootContext.register(MvcConfig.class); 
     rootContext.register(ApplicationContextProvider.class); 

     // Manage the lifecycle of the root application context 
     container.addListener(new ContextLoaderListener(rootContext)); 

     // Register and map the dispatcher servlet 
     ServletRegistration.Dynamic dispatcher 
       = container.addServlet("dispatcher", new DispatcherServlet(rootContext)); 

     dispatcher.setLoadOnStartup(1); 
     dispatcher.addMapping("/"); 

     // Create servlet for WS 
     MessageDispatcherServlet messageDispatcherServlet = new MessageDispatcherServlet(); 
     messageDispatcherServlet.setApplicationContext(rootContext); 
     messageDispatcherServlet.setTransformWsdlLocations(true); 

     ServletRegistration.Dynamic messageDispatcher 
       = container.addServlet("messageDispatcher", messageDispatcherServlet); 

     messageDispatcher.setLoadOnStartup(2); 
     messageDispatcher.addMapping("/ws/*"); 

一つ、石鹸Webサービスのための別のものを。

@EnableTransactionManagement(proxyTargetClass = true)注釈が設定されています。 私はHibernateTransactionManager beanとSessionFactoryを設定しています。

セッションファクトリは、@Transactionalおよび@Repositoryと注釈されたdb-through DAOにアクセスするために使用されます。

また、ほとんどの場合、SpringのThreadPoolTaskExecutorによって生成された新しいスレッドでさえ、すべてが魅力的に機能します。しかし

私はWSインターセプタの内側に私のDAOのリポジトリを使用しよう - SessionFactory.getCurrentSessionはで失敗します。

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread; 

現在問題は以下で解決されることがあります。

Session session; 
try { 
     session = sessionFactory.getCurrentSession(); 
} catch (HibernateException e) { 
    session = sessionFactory.openSession(); 
} 

しかし、言って真実私はこの解決策が嫌いです。

hibernate.format_sql    = false 
hibernate.show_sql    = false 
hibernate.dialect     = org.hibernate.dialect.MySQL5Dialect 
hibernate.hbm2ddl.auto   = update 
javax.persistence.validation.mode = none 

WSインターセプタの設定:ここでは

は私の休止状態の性質である

@Override 
public void addInterceptors(List<EndpointInterceptor> interceptors) { 

     PayloadRootSmartSoapEndpointInterceptor interceptor = new PayloadRootSmartSoapEndpointInterceptor(
       authEndpointInterceptor, LeadServiceEndpoint.NAMESPACE_URI, ""); 

     interceptors.add(interceptor); 

     super.addInterceptors(interceptors); 
} 

そこで質問です - 私のセッションファクトリビーンにはセッションがない理由、それはアクセスされたときSpring WSインターセプタから?

ご協力いただきありがとうございます。

追加詳細:

インターセプタ:

@Component 
public class AuthEndpointInterceptor implements EndpointInterceptor { 

    @Autowired 
    private AuthProvider defaultAuthProvider; 

    @Override 
    public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception { 

     // TODO Make marshaller as a bean 
     Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 
     marshaller.setPackagesToScan("com.itsupportme.gpipeline.component.soap.ws.types"); 

     SaajSoapMessage saajSoapMessage = (SaajSoapMessage) messageContext.getRequest(); 


     SoapBody requestBody = saajSoapMessage.getSoapBody(); 
     Object obj   = marshaller.unmarshal(requestBody.getPayloadSource()); 

     if (!(obj instanceof KeySignatureAware)) { 
      // TODO Implement bad response functionality 
      return false; 
     } 

     AuthResultInterface authResult = defaultAuthProvider.doAuth((KeySignatureAware) obj); 

     if (!authResult.getStatus()) { 
      // TODO Implement bad response functionality 
      return false; 
     } 


     return true; 
    } 

プロバイダ:

@Service 
@Transactional 
public class DefaultAuthProvider implements AuthProvider { 

    @Autowired 
    private CredentialsDao credentialsDao; 

    @Override 
    public AuthResultInterface doAuth(KeySignatureAware keySignatureAware) { 

     // Check key and signature 
     if (keySignatureAware.getKey() == null) { 
      return new AuthResult(false, "Key is not provided."); 
     } 

     if (keySignatureAware.getSignature() == null) { 
      return new AuthResult(false, "Signature is not provided."); 
     } 

     // Find if such credentials are there 
     Credentials credentials = credentialsDao.findByKey(keySignatureAware.getKey()); 
     if (credentials == null) { 
      return new AuthResult(false, "Invalid key provided"); 
     } 

     ... 
} 

DAO:

+0

解決策は解決策ではありません。あなたのトランザクションを管理するために春を使用しているときは、決して 'openSession'を使用しないでください!トランザクション設定に欠陥があるため、セッションはありません。リポジトリではなくデータに直接アクセスするには、トランザクションサービスレイヤーを使用する必要があります。 –

+0

私は知っている、それが私が助けを求めている理由です。問題は、私は多国籍のサービス層を使用することです。 –

+0

あなたの投稿によると、あなたのインターセプタのサービスではなく、リポジトリを使用しています... –

答えて

0
@Repository 
@Transactional 
public class CredentialsDaoImpl implements CredentialsDao{ 

    @Autowired 
    SessionFactory sessionFactory; 


    @Override 
    @SuppressWarnings("unchecked") 
    public Credentials findByKey(String key) { 

     List<Credentials> credentialsList; 

     Session session = sessionFactory.getCurrentSession();; 

     credentialsList = session 
       .createQuery("from Credentials where apiKey = :apiKey") 
       .setParameter("apiKey", key) 
       .list(); 

     if (credentialsList.size() > 0){ 
      return credentialsList.get(0); 
     } else { 
      return null; 
     } 
    } 
} 

Probl emは@Repository bean - CredentialsDaoImplPROTOTYPE_SCOPE beanとマークして解決しました。そして、レポを回収する。アプリケーションコンテキストからのインスタンス。

結果として、springはrepoを持つスレッド用の新しいリポジトリBeanを作成します。このスレッドに関連する適切なセッションを作成します(私の理解から)。

関連する問題