0

Java EE、Spring、EclipseLink、および Glassfish サーバーを使用して Web アプリケーションに取り組んでいます。

私のアプリケーションは、Spring でエンティティマネージャーを注入し、より良いトランザクション管理を有効にするために、Bean 構成を変更しようとする前に問題なく動作していました...動作しません... (その前に、すべての各データベース要求の前に emf.createEntityManager() を呼び出す必要があることを除いて、同じです)。

ここに私の設定ファイルがあります:

  • web.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    
     <!-- jsp config => automatic inclusions in all jsp files -->
    <jsp-config>
       <jsp-property-group>
         <url-pattern>/WEB-INF/views/*</url-pattern>
        <include-prelude>taglibs.jsp</include-prelude>
        <include-prelude>setLanguage.jsp</include-prelude>
    </jsp-property-group>
    </jsp-config>
    <display-name>MEANS</display-name>
    
    <!-- Beans in these files will makeup the configuration of the root web 
    application context -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/applicationContext.xml</param-value>
    </context-param>
    
     <!-- Bootstraps the root web application context before servlet initialization -->
      <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    
    <!-- Deploys the 'dispatcher' dispatcher servlet whose configuration resides 
    in /WEB-INF/spring/mvc-config.xml -->
     <servlet>
        <servlet-name>dispatcher</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/mvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
       <servlet-name>dispatcher</servlet-name>
       <url-pattern>*.do</url-pattern><!-- detect all urls ending with ".do" -->
    </servlet-mapping>
    
    <!-- Security Spring filter -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
       <filter-name>springSecurityFilterChain</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <session-config>
       <session-timeout>30</session-timeout><!-- the session is automatically 
        disconnected after 30 min of inactivity -->
    </session-config>
    
     <listener id="myLogger">
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
     </listener>
    
    <welcome-file-list>
         <welcome-file>index.do</welcome-file>
      </welcome-file-list>
    </web-app>
    
  • security-config.xml:

          <?xml version="1.0" encoding="UTF-8"?>
           <beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"             xmlns:util="http://www.springframework.org/schema/util"
         xmlns:security="http://www.springframework.org/schema/security"
         xsi:schemaLocation="http://www.springframework.org/schema/beans 
                       http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                       http://www.springframework.org/schema/util 
                       http://www.springframework.org/schema/util/spring-util-3.1.xsd
                       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
    
        <security:authentication-manager><!-- custom authentication manager-->
          <security:authentication-provider
        user-service-ref="userService">
          <security:password-encoder ref="passwordEncoder">
             <security:salt-source user-property="username" />
           </security:password-encoder>
          </security:authentication-provider>
        </security:authentication-manager>
    
       <bean id="passwordEncoder"
    class="org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder">
    <constructor-arg value="MD5" />
      </bean>
    
      <bean id="userService" class="fr.services.security.MyUserDetailsService"><!-- custom userDetailService -->
            <constructor-arg ref="myDAOFactory"/>
      </bean>
    
       <!-- disable authentication for those free access components-->
       <security:http pattern="/login.jsp*" security="none" />
       <security:http pattern="/disconnected.jsp*" security="none" />
       <security:http pattern="/css/**" security="none" />
       <security:http pattern="/javascript/**" security="none" />
       <security:http pattern="/jquery/**" security="none" />
    
      <security:http access-denied-page="/denied.jsp"   use-expressions="true">
    <security:form-login login-page="/login.jsp"
        authentication-failure-url="/login.jsp?errorMessage=invalidConnection"
        default-target-url='/index.do' always-use-default-target='false' />
    <security:intercept-url pattern="/admin*.do"
        access="hasRole('ROLE_ADMINISTRATEUR')" />
    <security:intercept-url pattern="/access*.do"
        access="isAnonymous() or isAuthenticated()" />
    <security:intercept-url pattern="/**"
        access="isAuthenticated()" />
    <security:logout logout-success-url="/disconnected.jsp" />
      </security:http>
    
       </beans>
    
  • persistence-config.xml:

      <?xml version="1.0" encoding="UTF-8"?>
       <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    
    
      <bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource"
      p:driverClassName="org.postgresql.Driver"
      p:url="jdbc:postgresql://localhost:5432/databaseName"
      p:username="postgres"
      p:password="pwd" />
    
     <tx:annotation-driven/>
    
     <tx:jta-transaction-manager>
       <property name="entityManagerFactory" ref="entityManagerFactory" />
     </tx:jta-transaction-manager>
    
     <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
      <property name="persistenceUnitName" value="databaseName" />
     </bean>
    
     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
       <property name="entityManagerFactory" ref="entityManagerFactory" />
      </bean>
     <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
    
    </beans>
    
  • アプリケーションコンテキスト.xml:

    <?xml version="1.0" encoding="UTF-8"?>
     <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:p="http://www.springframework.org/schema/p"
         xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
      <import resource="persistence-config.xml"/>
      <import resource="security-config.xml"/>
    
      <context:component-scan base-package="fr" />
    
      <context:annotation-config/>
    
    
        <!--  Define the location of the property file to change properties dependent on the application environment -->
         <context:property-placeholder location="/WEB-INF/configuration.properties" />
    
    </beans>
    
  • mvc-config.xml:

       <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
            http://www.springframework.org/schema/tx  
            http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd">
    
     <import resource="persistence-config.xml"/>
     <import resource="security-config.xml"/>
    
    
        <!-- Spring MVC Support for annotations (JSR-303) -->
      <mvc:annotation-driven>
    
      </mvc:annotation-driven>
    
      <context:component-scan base-package="fr.controller, fr.dao, fr.services" />
    
      <bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:prefix="/WEB-INF/views/" p:suffix=".jsp" />
    
      <bean id="urlMap" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
       <property name="urlMap">
        <map>
            <entry key="accessPasswordLost.do" value-ref="urlFilenameViewController"/>
            <entry key="documentation.do" value-ref="urlFilenameViewController"/>
            <entry key="hierarchyDialog.do" value-ref="urlFilenameViewController"/>
            <entry key="nameDialog.do" value-ref="urlFilenameViewController"/>
            <entry key="openCopyDialog.do" value-ref="urlFilenameViewController"/>
            <entry key="tableErosionParameterLS.do" value-ref="urlFilenameViewController"/>
            <entry key="training.do" value-ref="urlFilenameViewController"/>
            <entry key="userSettings.do" value-ref="urlFilenameViewController"/>
        </map>
    </property>
      </bean>
      <!-- For direct mapping between URL (i.e. index.htm index) and the JSP to render -->
       <bean id="urlFilenameViewController"
    class="org.springframework.web.servlet.mvc.UrlFilenameViewController">
       </bean>
    
       <import resource="aspects-config.xml"/>
    
     </beans>
    

persistence-config と security-config のインポートについてはよくわかりません...

すべての情報が揃っていることを確認するために、entitymanager を注入するクラス MyDAOFactory を次に示します。

 /**
 * A factory for creating DAO objects.
 */
@Component
public class MyDAOFactory implements IMyDAOFactory{

/** The map dao. */
private Map<Class<?>, IDao<?>> mapDAO;

/** The entity manager. */
@PersistenceContext(unitName="databaseName")
public EntityManager em;


/**
 * Instantiates a new my dao factory.
 */

public MyDAOFactory() {

    mapDAO = new HashMap<Class<?>, IDao<?>>();

}


/**
 * Gets the em.
 *
 * @return the em
 */
public EntityManager getEm() {
    return em;
}

/**
 * Sets the em.
 *
 * @param emf the new em
 */
public void setEm(EntityManager em) {
    this.em = em;
}



@Override
public <T extends Serializable> IDao<T> getBasicDAO(Class<T> entity) {
    if(mapDAO.containsKey(entity)){
        return (IDao<T>) mapDAO.get(entity);
    }else{
        BasicDAO<T> dao = new BasicDAO<T>(entity);
        dao.setEm(em);
        mapDAO.put(entity,  dao);
        return dao;
    }
}

}

そして、カスタム UserDetailsS​​ervice:

  @Transactional
  public class MyUserDetailsService implements UserDetailsService {

  /** The my dao factory. */
  IMyDAOFactory myDAOFactory;

/**
 * Instantiates a new means user details service.
 *
 */
public MyUserDetailsService(IMyDAOFactory myDAOFactory) {
    this.myDAOFactory = myDAOFactory;
}


/* (non-Javadoc)
 * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
 */
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException{
    IDao<Utilisateur> userDAO = this.myDAOFactory.getBasicDAO(Utilisateur.class);
    Map<String, String> map = new HashMap<String, String>();
    map.put("loginLdap", username);
    Utilisateur user = userDAO.findByAttributes(map).get(0);
    IMyUserDetails userDetails = new MyUserDetails(user.getLoginLdap(), user.getPwdLocal(), user.getActif(), user.getDateValidite().getTime()>System.currentTimeMillis(), true, true, AuthorityUtils.createAuthorityList("ROLE_"+user.getProfil().getNomProfil().toUpperCase()));
    userDetails.setUser(user);
    return userDetails;     
}

 }

デバッグ モードでサーバーを起動すると、myDAOFactory が MyUserDetailsS​​ervice に挿入されたときにエンティティ マネージャーがセットアップされたようですが、アプリにログインしようとすると、どういうわけか loadUserByName の呼び出しが行われなくなりました... (ただし、構成のこの部分は変更しませんでした...)。

どんな助けでも大歓迎です!

4

2 に答える 2

1

いくつかの指針:

  1. MVC 構成にセキュリティおよび永続化構成をインポートしないでください。これらは、Bean が MVC コンテキストに表示されるルート アプリ コンテキストで (インポートを介して) 既に定義されています。

  2. DriverManagerDataSource はテストでのみ使用できます。遅くとも本番環境では、実際のプーリング DataSource (たとえば、JNDI を介して検索されるコンテナ管理の DataSource) に置き換えてください。

  3. DataSource 構成を見ると、おそらく JTA を使用していません。<tx:jta-transaction-manager />その場合は、 Bean 定義を削除します

  4. デバッグして問題を特定します。永続性に関連する場合は、永続性 (JPA) とそれをテストするための単純な Bean だけを含む最小限のルート アプリケーション コンテキストから始めます。

    <bean class="pkg.Test" init-method="persistence" />

  5. 機能しない場合は、ここに詳細情報を投稿してください

于 2013-06-04T21:09:51.167 に答える
0

考えられるすべての構成を数日間試した後、Spring、eclipseLink、および Glassfish を使用したトランザクション管理の正しいソリューションを最終的に見つけました。

  • 主な問題は、applicationContext.xml と mvc-config.xml に含めた spring タグ context:component スキャンの誤った使用によるものでした。どうやら、Bean やトランザクションを共有しない 2 つの異なるコンテキストを作成するようです (「DispatcherServlet が別のアプリケーション コンテキストを作成する理由」を参照してください) 。
  • また、JTA、jndi:lookup、および LocalEntityManagerFactoryBean の間でさまざまな構成をテストしましたが、Glassfish と EclipseLink を使用すると、より制限が厳しくなるようです (JTA が唯一の実行可能なオプションです)。

いつか誰かを助けることができれば、ここに私の修正があります:

applicationContext.xml

<beans ...>

  <import resource="persistence-config.xml"/>
  <import resource="security-config.xml"/>

  <context:component-scan base-package="fr.dao, fr.services" /><!-- do not scan the controllers here  -->

  <context:annotation-config/>


  <!--  Define the location of the property file to change properties dependent on the application environment -->
  <context:property-placeholder location="/WEB-INF/configuration.properties" />

</beans>

mvc-config.xml

<beans >


<!-- Spring MVC Support for annotations (JSR-303) -->
<mvc:annotation-driven>
    <mvc:argument-resolvers>
        <bean class="fr.utils.CurrentUserWebArgumentResolver"></bean>
    </mvc:argument-resolvers>
</mvc:annotation-driven>

<context:component-scan base-package="fr.controller" /><!-- only scan controllers here -->

... 

<import resource="aspects-config.xml"/>

</beans>

そして、persistence-config.xml:

<beans ...>

 <tx:annotation-driven/>

 <!-- We want to locate the container transaction manager -->
 <bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
        <bean
            class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
            <property name="showSql" value="true" />
        </bean>
    </property>
    <property name="jpaDialect">
        <bean
            class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
    </property>
    <property name="persistenceUnitName" value="databaseName"/>
    <property name="persistenceUnitManager">
        <bean 
            class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"/>
    </property>
  </bean>   

  <tx:jta-transaction-manager/>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
</beans>
于 2013-06-10T16:39:46.053 に答える