I'm working on a web application using Java EE, Spring, EclipseLink and Glassfish server.
My application was working just fine before I tried to change my bean configuration in order to inject the entitymanager with Spring and to enable better transaction management... I don't get it to work... (before that I had it all the same, except I had to call emf.createEntityManager() before each database request).
Here are my configuration files :
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>
application-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>
I'm not sure about the imports for persistence-config and security-config...
To make sure, you have all the information, here is the class MyDAOFactory which gets the entitymanager injected:
/**
* 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;
}
}
}
And the custom UserDetailsService:
@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;
}
}
When I started the server in the debug mode, it seems that the entitymanager was set up when the myDAOFactory is injected in the MyUserDetailsService but somehow the call to loadUserByName does not happen anymore, when I try to login to my app... (although I did not change this part of the configuration...).
Any help vould be greatly appreciated!