2013-06-04 55 views
0

我正在使用Java EE,Spring,EclipseLink和Glassfish服務器的Web應用程序。Glassfish和EclipseLink不能正常工作的entitymanager的Spring注入

我的應用程序在我嘗試更改我的bean配置以便爲Spring注入entitymanager並啓用更好的事務管理之前工作得很好...我沒有得到它的工作...(在此之前,我除此之外,我必須在每次數據庫請求之前調用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> 
    
  • 安全-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> 
    
  • 持久-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> 
    
  • 應用程序的context.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> 
    

我不知道關於進口持久性配置和安全 - config ...

爲了確保您擁有所有信息,這裏是MyDAOFactory類,它獲取了entitymanager注:

/** 
* 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;  
} 

} 

當我開始在調試模式下的服務器,似乎EntityManager的成立時,myDAOFactory在MyUserDetailsS​​ervice,但不知何故被注入調用loadUserByName不會再發生,當我嘗試登錄到我的應用程序時...(儘管我沒有更改這部分配置...)。

任何幫助將不勝感激!

回答

0

嘗試了幾天所有可能的配置之後,我終於找到了使用彈簧的EclipseLink和Glassfish我的事務管理一個正確的解決辦法:

  • 主要問題是由於錯誤地使用了spring標記上下文:我在applicationContext.xml中以及在mvc-config.xml中包含的組件掃描。顯然,它創建了兩個不共享bean或事務的上下文(請參閱:Why DispatcherServlet creates another application context?
  • 我還測試了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> 
1

幾個要點:

  1. 不要在MVC配置導入安全性和持久性CONFIGS,他們已經在根應用程序上下文中定義(通過進口),其豆可見的MVC上下文

  2. DriverManagerDataSource這個只是測試使用,與真正的池DataSource替換它在生產(如容器管理的DataSource通過JNDI查找)在最新的

  3. 看着你DATAS wece配置,你可能不使用JTA。如果是這樣,請刪除<tx:jta-transaction-manager /> bean定義

  4. 調試以嘗試查明問題。如果是持續性相關的,開始只有持久性(JPA)的東西一個最小的根機應用環境和一個簡單的bean來測試它:

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

  5. 如果你不能得到它的工作,張貼在這裏更多信息

+0

感謝您的建議。我終於搞定了,所以我在下面發佈了正確的配置。再次感謝 – Coralie

相關問題