I am working on a project where we decided to add some interaction using jms and hornetq as provider.
I am quite new to Camel so I ran into a problem some if you may refer as trivial.
The goal was to initialize connection factory and add the jms component. However, as I understand it can't be done directly in the route configurator. So I created camel-config.xml and placed it to the resources/ directory.
I filled it in the following way:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
<prop key="java.naming.provider.url">jnp://localhost:1099</prop>
<prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop>
</props>
</property>
</bean>
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>ConnectionFactory</value>
</property>
</bean>
<bean name="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsQueueConnectionFactory"/>
</bean>
</beans>
The project doesn't use Spring so it was the only example of the xml I have found that doesn't make use of Spring.
In the route configurator I use routeBuilder.from("jms:queue:top").to("...");
However, when I start the project it throws FailedToCreateEndpointException and states
"No component found with schema: jms".
I suppose that the xml file is simply not used but I just can't understand how to point to it.
Looking forward to hearing any advice.
The <beans/> XML is a Spring configuration that has to be bootstrapped in some way. You may have a look at the Tomcat ActiveMQ example found here, showing how to do that in a servlet environment. Have a special look at web.xml:
<!-- location of spring XML files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:broker.xml,
classpath:camel-config.xml
</param-value>
</context-param>
<!-- the listener that kick-starts Spring, which loads the XML files and start our application -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Of course, you could also use a Java only setup as follows:
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
ModelCamelContext context = new DefaultCamelContext();
context.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
Related
The BeanNameUrlHandlerMapping is the default mapping strategy and is used if no other mapping strategies are defined in the ApplicationContext. My question is simple:
How can we change this default mapping strategy to SimpleUrlHandlerMapping for instance through defaultHandler property?
Can we change it with this configuration below :
<bean id="simpleHander" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/student/test=testController
</value>
</property>
<property name="defaultHandler" ref="simpleHandler">
</bean>
<bean id="testController" class="com.test.controller.TestController"/>
A web application can define any number of DispatcherServlets. Each servlet will operate in its own namespace, loading its own application context with mappings, handlers, etc. Only the root application context as loaded by ContextLoaderListener, if any, will be shared.
A dispatcher servlet can be configured only one implementation of HandlerMapping.
From spring documentation
DispatcherServlet can use any HandlerMapping implementation - pre-built or provided as part of an application - to control the routing of requests to handler objects. Default is BeanNameUrlHandlerMapping and RequestMappingHandlerMapping. HandlerMapping objects can be defined as beans in the servlet's application context, implementing the HandlerMapping interface, overriding the default HandlerMapping if present. HandlerMappings can be given any bean name (they are tested by type).
1. How to configure SimpleUrlHandlerMapping
Configuring SimpleUrlHandlerMapping means configuring dispatcher servlet to use SimpleUrlHandlerMapping as HandlerMapping. It can be done in your dispatcher servlet configuration xml file. So first configure your dispatcher servlet to use a xml file for initializing.
In your web.xml
<servlet>
<servlet-name>simpleUrlHandlerDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/simpleUrlHandlerMapping.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>simpleUrlHandlerDispatcherServlet</servlet-name>
<url-pattern>*.simple</url-pattern>
</servlet-mapping>
In Your simpleUrlHandlerMapping.xml
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.simple">simpleHello</prop>
<prop key="/hi.simple">simpleHi</prop>
</props>
</property>
</bean>
<bean name="simpleHello" class="com.pvn.HelloController" />
<bean name="simpleHi" class="com.pvn.HiController" />
2. Alternatives of injecting values for mappings property in SimpleUrlHandlerMapping
As mappings property need java.util.Properties We can use any of the below
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.simple">simpleHello</prop>
<prop key="/hi.simple">simpleHi</prop>
</props>
</property>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/hello.simple=simpleHello
/hi.simple=simpleHi
</value>
</property>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<util:properties location="classpath:url-mappings.properties">
</util:properties>
</property>
</bean>
For last method, you need to create properties file in classpath as given below
And also you need to add XSD for your xml to avail <util:properties> tag.
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
I have been working with the Spring framework for a few days trying to set up a project, based off of something like this tutorial.
Unfortunately, when i deploy the project using Tomcat, I get a screen that looks something like this:
I'm not really sure to go from here. I've checked the web.xml and any other relevant .xml files that would maybe affect the error, but I can't see an error. Below I will post my web.xml and spring-config.xml files.
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Campaign Spring V2</display-name>
<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-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
spring_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:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="com.bridge.campaignspring.controller" />
<context:property-placeholder location="classpath:application.properties" />
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.bridge.campaignspring.Campaign</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="CampaignDao" class="com.bridge.campaignspring.dao.CampaignDAOImpl" />
<bean id="CampaignService" class="com.bridge.campaignspring.service.CampaignServiceImpl" />
</beans>
If need be, I can post the project to GitHub to see if there is an even larger flaw that could be found in the code. Also, if any other parts of the project need to be posted I will update the OP to display anything. Thanks!
EDIT: http://localhost/ does not load either, I was incorrect with my previous statement.
EDIT2: Here is a link to the project on GitHub.
EDIT3: After going through the Spring tutorial again this was resolved!
You didn't follow the tutorial well. The controller mapping starts with
#RequestMapping("/")
public class AppController {
The first annotation #RequestMapping("/") is important for spring to calculate the path used by the request.
And this code is missing
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.bridge.compaignspring.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
Without it Spring cannot autowire properties that depend on sessionFactory.
Just done a quick check through the github project, you have more problems that I thought.
You are using XML config to create the DispatchServer with the config at Spring-config.xml, while also having a AppInitializer on the class path.
The AppInitializer uses AppConfig which creates a Datasource bean, your XML also creates a Datasource bean and also a SessionFactory.
Tomcat will find the AppInitializer and is running through that first.
This means it tries to autowire the SessionFactory before the one in the XML have been created.
To move your code off this problem do the following things.
move spring_config.xml from /webapp/WEB-INF to /resources
add the following #import line to AppConfig.java
#Configuration
#EnableWebMvc
#ImportResource("classpath:spring-config.xml")
#ComponentScan(basePackages = "com.bridge.campaignspring")
public class AppConfig {
Now you need to remove 1 of the 2 DataSource beans you are creating. I would suggest removing the one in the XML as that is using invalid property values. i.e. ${database.driver} does not exist.
After you have made those changes, you will still have other problems, but you are further along than you were.
did u set Web Module Path in tomcat settings ?
refer these question Unable to run Spring REST application using Tomcat
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.
I've got a strange problem which I think is Spring related. I'm developing a Maven multi module application structured as follow:
DataModule (includes generale Hibernate entities and daos)
ServiceModule (includes specific Hibernate entities and daos) - depends on DataModule
Web (gwt web module) - depends on ServiceModule
In DataModule I've a classic Spring-Hibernate xml configuration, consisting of (relevant code):
ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans ..>
<!-- Auto scan the components -->
<context:annotation-config />
<context:component-scan base-package="com.x.dataModule" >
<context:include-filter type="regex"
expression="com.x.dataModule.dao.*" />
</context:component-scan>
<!-- Import resources -->
<import resource="applicationContext-hibernate.xml" />
<import resource="applicationContext-dataSource.xml" />
</beans>
applicationContext-hibernate.xml
<beans ..>
<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean ">
<property name="packagesToScan" value="com.x.dataModel.model.**.*"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="lobHandler" ref="defaultLobHandler" />
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.query.substitutions">true 1, false 0</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.charSet">UTF8</prop>
</props>
</property>
</bean>
<!-- Transaction Manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
</beans>
Hibernate.cfg is actually empty, since I aim to avoid explicit mapping due the use of packagesToScan property. applicationContext-dataSource is not relevant since it contains ds configuration.
The ServiceModule relies on the previous module.
applicationContext.xml
<beans ...>
<!-- Auto scan the components -->
<context:include-filter type="regex"
expression="com.x.serviceModule.dao.*" />
<context:include-filter type="regex"
expression="com.x.serviceModule.manager.*" />
<!-- Import resources -->
<context:property-override location="classpath:override.properties"/>
<import resource="classpath*:/applicationContext-hibernate.xml" />
<import resource="classpath*:/applicationContext-dataSource.xml" />
</beans>
The file override.properties contains the following entry, to modify the definition of packagesToScan
sessionFactory.packagesToScan=com.x.*.model.**.*
At this point everything works just fine. The serviceManagers (singletons) are loaded from the factory as
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"applicationContext.xml").getBean(..);
And everything is behaving as expected.
Last part, the Web Module. If I import the ServiceModule and test it as a Java application, again everything is fine. However, if I start the module as a web application, it fails complaining that it's not able to load entities/daos defined in the DataModule.
Relevant files in Web Module:
WEB-INF/spring
applicationContext.xml: nothing here other than the import of applicationContext-security.xml (residing in the same directory)
web.xml
<!-- Spring context -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/spring/applicationContext.xml
</param-value>
</context-param>
<!-- Creates the Spring Container -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
The only way to avoid the problem is to declare explicitly the entities mapping and daos definition in the DataModule xml files.
My question: is there a way to avoid such declarations, and rely entirely on the component/package scan also in Web Module?
I'm not really sure but looks like that somehow the spring web context is conflicting with my other spring context. Otherwise, I don't understand why everything is fine as Java application, but fails as web.
Also (not sure if relevant) it seems that the Session Factory bean is istantiated twice during the process (shouldn't it be a singleton?).
Spring version is 3.1.1 Release, Hibernate 3.6.0 Final (4.0.1 for commons-annotations). Tomcat 7 for deploy.
I didn't provide the Java code of entities/daos/managers since I don't think it's relevant for the question; however, I can provide it if it's of any help. Thanks a lot
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 ?