JavaEE/Spring: Just call method on initialized bean using xml? - java

I have multiple config files in my web.xml:
<!-- Spring MVC ========================================================================== -->
<servlet>
<servlet-name>MoJV_SpringMVCDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/mo/MoJV/config/MoJVConfig.xml
/mo/App/config/AppConfig.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
In MoJVConfig.xml i have
<bean id="messageSource" class="mo.MoJV.src.I18N">
<property name="defaultEncoding" value="utf-8" />
<property name="fallbackToSystemLocale" value="true" />
<property name="cacheSeconds" value="3" />
<property name="files" value="/mo/MoJV/i18n/" />
</bean>
In AppConfig.xml I would like to only call setWorkingDirectory on the same messagesource. I have tried with
<bean id='messageSource'>
<property name="files" value="/mo/App/i18n/" />
</bean>
but that didnt work. I have tried a bunch of other things as well which hasnt worked.
I dont want a new bean, I want the first declaration to actually run, initialize the bean and then my second declaration to call a method on that bean.
Is this not possible?

I guess you may want this
<bean id="myBean" class="com.acme.MyClass" init-method="yourInitMethod">
<property ...>
</bean>
Init-method will be called after injecting all properties and after constructor.

Related

Mystery around Spring Integration and prototype scope

Well, very likely there isn't any mystery but I am just not smart enough to figure out what my problem is. However usually it is the mystery after all!
Sorry for the introduction, my problem is that the prototype scope doesn't seem to work for me. I have created a REST service with a Spring Integration flow (there is a http inbound gateway in the front of the flow). The scopes of most of the beans are prototype. I tested the flow by calling it ten times with threads. Also I logged the bean references (just print the 'this' in the object being called) and I saw the same reference ten times!
e.g. org.protneut.server.common.utils.XmlToMapConverter#755d7bc2
To my knowledge it means that no new instance is being created for the XmlToMapConverter but using the same instance ten times. Am I right?
Very likely I configured the Spring incorrectly but I just cannot find out what I missed.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/SpringIntegration-servlet.xml</param-value>
</context-param>
<servlet>
<servlet-name>SpringIntegration</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringIntegration</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
SpringIntegration-servlet.xml
<beans ...>
<mvc:annotation-driven/>
<context:component-scan base-package="org.protneut.server.controller, org.protneut.server.common.persistence.service" />
<jpa:repositories base-package="org.protneut.server.common.persistence.repository"/>
<!-- ********************* importing the mysql config ********************* -->
<import resource="/mysql-config-context.xml"/>
<!-- ********************* importing the message flow ********************* -->
<import resource="classpath:META-INF/spring/integration/processing_req_wokflow.xml"/>
<tx:annotation-driven />
<!-- ************************************************************************* -->
<!-- ******************************** for JPA ******************************** -->
<!-- ************************************************************************* -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.protneut.server.common.persistence.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- ********************* the used property files ********************* -->
<context:property-placeholder location="classpath:protneut-server-config.properties"/>
<!--
****************************************************************************************
********************** Beans used in the Spring Integration flow **********************
****************************************************************************************
-->
<!-- it has to be prototype, it cannot be request as it is in an async call so it is not in the request! -->
<bean id="logManager" class="org.protneut.server.log.LogManager" scope="prototype"></bean>
<bean id="convertRestToWorkflowBean" class="org.protneut.server.rest.ConvertRestMessageToWorkflowBean" scope="prototype"/>
<bean id="xmlToMapConverter" class="org.protneut.server.common.utils.XmlToMapConverter" scope="prototype"/>
<bean id="serviceStorageManager" class="org.protneut.server.cache.ServiceStorageManager" scope="singleton">
<property name="cacheBeanDAO" ref="cacheBeanDAO"/>
</bean>
<bean id="serviceCall" class="org.protneut.server.call.ServiceCall" scope="prototype">
<property name="httpClient" ref="httpClient"/>
</bean>
<bean id="xmlResponseExtractor" class="org.protneut.server.extract.XmlResponseExtractor" scope="prototype">
<property name="xmlToMapConverter" ref="xmlToMapConverter"/>
</bean>
...
</beans>
flow configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans ..>
<task:executor id="async_executor" pool-size="50" />
<!-- ***************************************************************************************************** -->
<!-- ************************************* WORKFLOW STARTING ********************************************* -->
<!-- ***************************************************************************************************** -->
<int-http:inbound-gateway id="receivingRest-inboundGateway"
supported-methods="POST" path="/service/get"
request-payload-type="java.lang.String" reply-timeout="10000"
request-channel="arrivedRestReq_channel" auto-startup="true"
error-channel="error_channel" reply-channel="restResponse-channel" >
</int-http:inbound-gateway>
<int:channel id="arrivedRestReq_channel" scope="prototype"></int:channel>
<int:json-to-object-transformer type="java.util.Map"
input-channel="arrivedRestReq_channel"
output-channel="fromConvertToActivator-channel"
id="convertJsonToMap_">
</int:json-to-object-transformer>
<int:channel id="fromConvertToActivator-channel"></int:channel>
<int:service-activator
input-channel="fromConvertToActivator-channel"
output-channel="toCallChain-channel"
id="convertRestToWorkflowBean-serviceActivator"
ref="convertRestToWorkflowBean" method="convert">
</int:service-activator>
<int:channel id="toCallChain-channel"></int:channel>
<int:chain input-channel="toCallChain-channel" id="call_chain">
<int:service-activator
id="serviceStorageManager-serviceActivator"
ref="serviceStorageManager" method="getServiceInfo">
</int:service-activator>
<int:service-activator id="serviceRequestCreator-serviceActivator" ref="serviceRequestCreator" method="create"/>
<int:service-activator id="call-serviceActivator"
ref="serviceCall" method="call">
</int:service-activator>
<int:router expression="payload.extractType.name()"
id="responseExtractor-router">
<int:mapping value="XPATH" channel="xmlResponse-channel"/>
<int:mapping value="JSONPATH" channel="jsonResponse-channel"/>
</int:router>
</int:chain>
...
<int:service-activator id="xmlResponseExtractor-serviceActivator"
ref="xmlResponseExtractor" method="extract" input-channel="xmlResponse-channel" output-channel="toRestResponseCreator_chain"></int:service-activator>
</beans>
So I defined the scope of XmlToMapConverter is prototype but still I can't have new object at a new request. The situation is the same for convertRestToWorkflowBean which is the first service call in the flow (service-activator).
Could you please explain to me where the problem is?
Thanks, V.
I don't see xmlToMapConverter usage, but I see this:
<int:service-activator
input-channel="fromConvertToActivator-channel"
output-channel="toCallChain-channel"
id="convertRestToWorkflowBean-serviceActivator"
ref="convertRestToWorkflowBean" method="convert">
where you use this:
<bean id="convertRestToWorkflowBean" class="org.protneut.server.rest.ConvertRestMessageToWorkflowBean" scope="prototype"/>
The issue you are facing is called scope impendance. That's because <int:service-activator> populates several singleton beans, hence the reference to your prototype becomes as singleton, too.
One way to overcome that to use SpEL from there:
<int:service-activator
input-channel="fromConvertToActivator-channel"
output-channel="toCallChain-channel"
id="convertRestToWorkflowBean-serviceActivator"
expression="#convertRestToWorkflowBean.convert(payload)"/>
In this case your convertRestToWorkflowBean is retrieved from the BeanFactory on each call.
Another trick to go ahead looks like:
<bean id="convertRestToWorkflowBean" class="org.protneut.server.rest.ConvertRestMessageToWorkflowBean" scope="prototype">
<aop:scoped-proxy/>
</bean>
In this case your bean will be wrapped to the ScopedProxyFactoryBean and all invocation will be delegated to your prototype on demand.
Prototype scoped beans will be created every time you call ApplicationContext.getBean(...)
You've included the bean definition but haven't shown how other services reference it. My guess is it's injected into a singleton service once during initialization hence there's only one. Perhaps you need to call ApplicationContext.getBean() each time to get a new instance.
There are other solutions involving dynamic proxies that ultimately invoke getBean(), I'm on my mobile at the moment so too hard to find a link for you.

Configuration Hazelcast and Shiro

I am currently having trouble configuring Shiro and Hazelcast in conjunction:
web.xml:
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter>
<filter-name>hazelcastWebFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
[...]
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>hazelcastWebFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
ApplicationContext.xml:
<!-- Hazelcast configuration-->
<hz:hazelcast id="hazelcastInstance">
<hz:config>
<hz:instance-name>${hazelcast.instance}</hz:instance-name>
<hz:group name="${hazelcast.group}" password="${hazelcast.password}"/>
<hz:network port="${hazelcast.port}" port-auto-increment="${hazelcast.port.autoincrement}">
<hz:join>
<hz:multicast enabled="${hazelcast.multicast.enabled}"
multicast-group="${hazelcast.multicast.group}"
multicast-port="${hazelcast.multicast.port}"
multicast-time-to-live="${hazelcast.multicast.timetolive}"
multicast-timeout-seconds="${hazelcast.multicast.timeoutseconds}"></hz:multicast>
</hz:join>
</hz:network>
</hz:config>
</hz:hazelcast>
[...]
<bean id="hazelcastWebFilter" class="com.hazelcast.web.WebFilter" depends-on="hazelcastInstance">
<constructor-arg name="properties">
<props>
<prop key="map-name">shiro-activeSessionCache</prop>
<prop key="sticky-session">${hazelcast.webfilter.stickysession}</prop>
<prop key="instance-name">${hazelcast.instance}</prop>
</props>
</constructor-arg>
</bean>
<!-- Shiro -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/s/Login.app"/>
<property name="successUrl" value="/goMain.app"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
<property name="filters">
<util:map>
<entry key="authc" value-ref="auth"/>
<entry key="authcpda" value-ref="pdaAuth"/>
</util:map>
</property>
<property name="filterChainDefinitions">
<value>
HERE ARE PATHS onfigured
</value>
</property>
</bean>
<bean id="auth" class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter">
<property name="loginUrl" value="/s/Login.app"/>
</bean>
<bean id="pdaAuth" class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter">
<property name="loginUrl" value="/s/pda/login.app"/>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="PRODUCTRealm"/>
<property name="cacheManager" ref="shiroCacheManager"/>
<property name="sessionManager" ref="sessionManager"/>
</bean>
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"></bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!--<bean id="shiroCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/>-->
<bean id="shiroCacheManager" class="de.logentis.Hazelcast.HazelcastCacheManager"/>
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionDAO" ref="sessionDAO"/>
<property name="sessionValidationSchedulerEnabled" value="false"/>
</bean>
<!-- Define the Shiro Realm implementation you want to use to connect to your back-end -->
<!-- security datasource: Netversys DB -->
<bean id="PRODUCTRealm" class="PRODUCTNAMEJdbcRealm">
<property name="dataSource" ref="dataSource"/>
<property name="schema" value="${PRODUCTdb.schema}"/>
</bean>
<!-- Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor has run: -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
HazelcastCacheManager is from: https://github.com/stormpath/shiro-hazelcast-web-sample/blob/master/src/main/java/com/stormpath/samples/shiro/hazelcast/cache/HazelcastCacheManager.java
Problem 1: I can't log into the Application. I'm instantly logged out.
Problem 2: A JSESSIONID appears as query parameter (?). Was definitely never before
Problem 3: The hazelcastsession seems lost, although a Cookie exists
Problem 4: I have 3 Cookies: 2 JSESSIONID and 1 hazelcast.
Any help will be appreciated
As for the JSESSIONID issues, which may cause 1)
I don't know about hazelcast, but we had similar issues with using Vaadin and shiro. When the webapplication was using the JSESSION in the url, things got messy.
What helped for us is adding this to web.xml, telling the webserver to only use cookies for session id tracking:
<session-config>
<cookie-config>
<!-- this is so we also use it for https -->
<http-only>false</http-only>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>

Right configuration for spring mvc app

I read this "It is a best practice to keep a clear separation between middle-tier services such as business logic components and data access classes (that are typically defined in the ApplicationContext) and web- related components such as controllers and view resolvers (that are defined in the WebApplicationContext per Dispatcher Servlet)."
And decide configure my application like that 4 separate xml file
applicationContext.xml
<context:component-scan base-package="appname">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
dao.xml
<!-- MySQL JDBC Data Source-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://#{mysqlDbCredentials.hostname}:#{mysqlDbCredentials.port}/#{mysqlDbCredentials.name}"/>
<property name="username" value="#{mysqlDbCredentials.username}"/>
<property name="password" value="#{mysqlDbCredentials.password}"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="JpaPersistenceUnit" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.showSql">true</prop>
</props>
</property>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
and mvc-dispatcher-servlet.xml
<mvc:annotation-driven />
<context:component-scan base-package="appname" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
web.xml(load spring context)
<servlet>
<servlet-name>mvc-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-dispatcher-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>
<!-- Load spring beans definition files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/applicationContext.xml
/WEB-INF/spring/security.xml
/WEB-INF/spring/dao.xml
</param-value>
</context-param>
But I'm absolutly confused.
1)I don't understand how many context in this case I get.
2)I want easy replace tx mode on aspectj (which work just in ome context as I know). But when I replace I get error with transation.
Main problem that I want to have universal variant for both type of transaction
Here I add mode="aspectj" and I have annotation like #Service, #Resourse, on concrete classes
<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj" proxy-target-class="true"/>
All seems should work but I get next exception on flush
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1239)
at [internal classes]
at org.apache.logging.log4j.core.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:66)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:194)
at [internal classes]
Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:993)
at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-2)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
Please, help me uderstand better
convention is you have one root context, normally applicationContext.xml. Then different servlet contexts (for different modules/functionality)... myapp-servlet.xml.
The servlet context can see everything in root context, but not the other way. Controllers and webby stuff(static resources) go in servlet context, everything else (eg service, and security) go in root context.
You can import different files as you please. But define those two contexts in your web.xml (or Java conf equivalent).
I still do it the old fashioned xml way, you don't have to use java conf.
Whats your actual error ?

Spring message bundle issue

I've got a spring-security setup in my web-app. I want to replace some messages of spring security with my custom messages i.e.
Instead of Bad Credentials I want AbstractUserDetailsAuthenticationProvider.badCredentials to have value invalid username or password, please try again
This is my spring setup :
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages/messages"/>
<!-- Tried this as well <property name="basename" value="/WEB-INF/messages/messages.properties"/> -->
<property name="cacheSeconds" value="0" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
And I have created folder in the WEB-INF called messages. Inside this folder there is file called messages.properties. Inside this file is one line :
AbstractUserDetailsAuthenticationProvider.badCredentials=invalid username or password, please try again
What am I doing wrong here?
Update :
This servlet-context is defined in the web xml :
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Problem solved, moved the messageSource bean definition to another context.
Everything looks right. Try to get the message using spring message tag in order to check if the problem is with your configuration or with the security message:
<spring:message code="AbstractUserDetailsAuthenticationProvider.badCredentials" />
If this does work, problem is not with your configuration (that looks fine for me).
Anyway, try to put your messages files in the classpath (source folder) and this:
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages/messages"/>
<property name="cacheSeconds" value="0" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
Also, check that the bean is being declared in a application context file that Spring is aware of.

Proper injection of SessionFactory with Spring and Spring Security

i have this exception
java.lang.NullPointerException
cz.xkadle21.dip.dao.ADiHibernateGenericDAO.findByCriteria(ADiHibernateGenericDAO.java:116)
cz.xkadle21.dip.dao.impl.DiUserDAO.findUserByUsername(DiUserDAO.java:86)
cz.xkadle21.dip.service.impl.DiUserContextSecurityService.loadUserByUsername(DiUserContextSecurityService.java:47)
cz.xkadle21.dip.service.impl.DiUserContextSecurityService.loadUserByUsername(DiUserContextSecurityService.java:1)
I was following this tutorial Spring Security 3 database authentication with Hibernate
and got "No bean named ... is defined" error. So i moved beans from dispatcher-servlet.xml to applicationContext-common-business.xml and change loading in web.xml
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-common-business.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Beans in despatcher-servlet.xml are loading with component-scan and are injecting sessionFactory automaticaly and properly. But bean in applicationContext-common-business.xml not.
applicationContext-common-business.xml
<bean name="userDetailsService"
class="cz.xkadle21.dip.service.impl.DiUserContextSecurityService" >
<constructor-arg ref="userDAO" />
<constructor-arg ref="securityUserFactory" />
</bean>
<bean id="securityUserFactory" class="cz.xkadle21.dip.factory.impl.DiSecurityUserFactory" />
<bean id="userDAO" class="cz.xkadle21.dip.dao.impl.DiUserDAO" />
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${hibernate.connection.driver_class}"
p:url="${hibernate.connection.url}" p:username="${hibernate.connection.username}"
p:password="${hibernate.connection.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
</props>
</property>
</bean>
UserDetailsService is injected via constructor, but how to inject sessionFactory to userDAO? SessionFactory is defined in ADiHibernateGenericDAO and all DAOs extend the abstract ADiHibernateGenericDAO.The exception above is thrown on SessionFactory, which is not injected.
Thanks for any response.
Mate, I don't see any Transaction Manager or
< tx:annotation-driven />
written anywhere in your bean configuration file. You should put it there if you already haven't. That might be the problem.
You haven't shown us your DiUserDAO class, but assuming you have a setter in it for setSessionFactory(), you could simply change your XML mapping to be like:
<bean id="userDAO" class="cz.xkadle21.dip.dao.impl.DiUserDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Alternatively you could modify your DiUserDAO class to mark the SessionFactory field as #Autowired.
The same solution applies to any other beans that need to access this bean.

Categories