Spring + 2 Hibernate datasources + 2 TransactionManagers: NoSuchBeanDefinitionException - java

I have a Spring Web application with two Hibernate data sources, and they are being managed with two separate transaction managers. The datasources are completely independent, schema-wise. This configuration passes all unit tests and integration tests, but when I deploy it in Jetty, the repository operations fail with the below exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named my_transactionManager1' is defined: No unique PlatformTransactionManager bean found for qualifier 'my_transactionManager1'
at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:84)
at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:55)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:246)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:100)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
at my.controller.Class$$EnhancerByCGLIB$$3976e5ef.myMethodCall(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
persistence.xml
<persistence-unit name="pu1">
<properties>
<property name="hibernate.dialect" value="${hibernate.dialect}" />
<property name="hibernate.connection.url" value="${network.db.url}" />
<property name="hibernate.connection.driver_class" value="${hibernate.connection.driver_class}" />
<property name="hibernate.connection.username" value="{db.username}" />
<property name="hibernate.connection.password" value="{db.password}" />
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="${hibernate.hbm2ddl.auto}" />
<property name="hibernate.show_sql" value="false" />
</properties>
Looking at the logs, both datasources seems to behave sanely (until this error occurs). Below is the application context:
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
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.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<tx:annotation-driven transaction-manager="my_transactionManager1" />
<context:component-scan base-package="com.my.package"/>
<jpa:repositories
base-package="com.my.package" entity-manager-factory-ref="my_entityManagerFactory" transaction-manager-ref="my_transactionManager1">
</jpa:repositories>
<bean id="my_dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="${my.db1.url}"/>
<property name="username" value="${db1.username}"/>
<property name="password" value="${db1.password}"/>
</bean>
<bean id="my_entityManagerFactory1"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="pu1" />
<property name="dataSource" ref="my_dataSource1" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${hibernate.dialect}"/>
<property name="generateDdl" value="false" />
<property name="database" value="HSQL"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>
<bean id="my_transactionManager1" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="my_entityManagerFactory1" />
<property name="dataSource" ref="my_dataSource1" />
<qualifier value="my_transactionManager1"/>
<property name="persistenceUnitName" value="pu1"/>
</bean>
</beans>
My Service Class where I'm trying to inject the TransactionManager:
Service
#Transactional(value="my_transactionManager1")
#PersistenceContext(unitName = "pu1", name="my_entityManagerFactory1")
public class MyServiceClass{
#Autowired
private Field myField
#Resource(name="my_transactionManager1")
private JpaTransactionManager my_transactionManager1;
/**
* Public no-arg constructor for bean initialization
*/
public MyServiceClass() {}
/**
* Protected IOC constructor for testing
*
* #param resultsService
*/
protected MyServiceClass(Field myField) {
this.myField = myField;
}
I have tried a lot of different approaches to work around this problem. One thing that is often suggested for this situation is a single JTA XA TransactionManager, but I would like to avoid that, at least for this first pass. Another thing that is suggested is using an AbstractDataRoutingSource, but I don't really want that either. The approach I have seems tenable (if not optimal), because tests are passing and the application deploys without error. Here is my web.xml (sorry for lengthy post):
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="site" 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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:my-first-context-file.xml,
classpath:a-few-other-config-files.xml,
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
<servlet>
<servlet-name>MyServeletName</servlet-name>
<servlet-class>
com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>
com.sun.jersey.config.property.packages
</param-name>
<param-value>com.my.package</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
</load-on-startup>
</servlet>
<!--More servlets -->
<!-- Servlet mapping stuff -->
</web-app>
Any help at all would be much appreciated.

Make sure, you have unique ids of beans. It seems like you have 2 transactionManager beans with id="my_entityManagerFactory1"
Any way, you should add to annotation propagation value:
#Transactional(propagation=Propagation.REQUIRED, value="my_entityManagerFactory1")
Similar problem (one entity in 2 databases) I have solved by inheritence:
#MappedSuperclass
public class User{
private String name;
private String surname;
private String login;
private String password;
}
#Entity
public class Employee extends User{
//....
}
#Entity
public class CLient extends User{
//...
}
Employee and Client classes were in different subpackages of entity package.
One sessionFaction scanned first subpackage, other sessionFactory scanned second one.
I had two services with #Transaction annotation like above and serched both databases by one manager class.
On application I used only User entity

I "solved" the problem by combining the two databases into one.

Related

Spring not dinfing dispatchServlet

I am new to spring. And I have encounter an error on my spring application. It says :
GRAVE: Servlet [dispatcher] in web application [/web-customer-function] threw load() exception
java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1309)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1137)
at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:546)
I have beean dealing with this for a long time now... It has been 5 days. And this is what I have done...
Deployment Asssembly > Add lib folder to path
Stop,clean or/and delete server
Rewrite entire code
Download the org.springframework.web.servlet.DispatcherServlet and try to run again.
I would appreciate the help to all if possible.
This is my Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>spring-mvc-crud-demo</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<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-crud-demo-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
And this part is my spring-crud.xml which are beans and configurations...
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Add support for component scanning -->
<context:component-scan base-package="com.luv2code.springdemo" />
<!-- Add support for conversion, formatting and validation support -->
<mvc:annotation-driven/>
<!-- Define Spring MVC view resolver -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Step 1: Define Database DataSource / connection pool -->
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false" />
<property name="user" value="springstudent" />
<property name="password" value="springstudent" />
<!-- these are connection pool properties for C3P0 -->
<property name="initialPoolSize" value="5"/>
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="maxIdleTime" value="30000" />
</bean>
<!-- Step 2: Setup Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="com.luv2code.springdemo.entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Step 3: Setup Hibernate transaction manager -->
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- Step 4: Enable configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="myTransactionManager" />
<!-- Add support for reading web resources: css, images, js, etc ... -->
<mvc:resources location="/resources/" mapping="/resources/**"></mvc:resources>
</beans>
And there is a Controller class... Just in case ...
package com.luv2code.springdemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("/customer")
public class CustomerController {
#RequestMapping("/list")
public String listAll(Model model) {
return "list-customers";
}
}
I got the problem fixed...
Thank you all for the help it made my think again. So I refactor the code from zero checked the libraries and it ran smoothly. So the issue was with the libraries because after refactoring the code it did not work. But checking the libraries it worked.

How to implement Spring's #Transactional Annotation using Hibernate, HikariCP and persistence.xml

I need to implement Spring's #Transactional annotation but I'm not being able to do so.
I had tried a lot of methods in the past 3 weeks but none of them worked.
I'm also need to use EntityManager. To test if Spring's was working, I tried to inject the EntityManager using #PersistenceContext (I also tried using #PersistenceUnit and/with EntityManagerFactory) but always I got nullPointerException.
#PersistenceContext(unitName = "sistema")
protected EntityManager entityManager;
Basically I need to know how to make spring's annotations to work and how to implement a Transaction manager using those technologies:
persitence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="sistema" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.sis.vo.Person</class>
<properties>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.enable_lazy_load_no_trans" value="false"/>
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false"/>
<!-- do I need those? -->
<property name="hibernate.connection.url" value="jdbc:mysql://localhost/myDatabase?autoReconnect=true&useSSL=false" />
<property name="hibernate.connection.username" value="myUser" />
<property name="hibernate.connection.password" value="myPass" />
</properties>
</persistence-unit>
</persistence>
spring.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<context:annotation-config />
<mvc:annotation-driven />
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="sisHikariCP" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="dataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
<property name="minimumIdle" value="3" />
<property name="maximumPoolSize" value="100" />
<property name="idleTimeout" value="740000" />
<property name="maxLifetime" value="1740000" />
<property name="leakDetectionThreshold" value="30000" />
<property name="dataSourceProperties">
<props>
<prop key="url">jdbc:mysql://localhost/myDatabase?autoReconnect=true&useSSL=false</prop>
<prop key="user">myUser</prop>
<prop key="password">myPass</prop>
<prop key="prepStmtCacheSize">350</prop>
<prop key="prepStmtCacheSqlLimit">2048</prop>
<prop key="cachePrepStmts">true</prop>
<prop key="useServerPrepStmts">true</prop>
<prop key="useLocalSessionState">true</prop>
<prop key="useLocalTransactionState">true</prop>
<prop key="rewriteBatchedStatements">true</prop>
<prop key="cacheResultSetMetadata">true</prop>
<prop key="cacheResultSetMetadata">true</prop>
<prop key="cacheServerConfiguration">true</prop>
<prop key="elideSetAutoCommits">true</prop>
<prop key="maintainTimeStats">false</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<bean id="myJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="myJpaVendorAdapter" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
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: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">
<display-name>sis</display-name>
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<welcome-file-list>
<welcome-file>index.jsf</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<!-- SPRING -->
<servlet>
<servlet-name>Spring Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
DAO
#Repository
public class GenericListDAO<E> {
#PersistenceContext(unitName = "sistema")
protected EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
public GenericListDAO() {
}
//rest of the code (persist, find, etc)
}
Versions:
Spring Version: 4.3.12
Hibernate Version: 5.1.10.Final
HikariCP Version: 2.7.3
JDK Version: 1.8.0_121
Tomcat version: 8.5.23
Thank you!
This is what i use to configure my transaction manager
<bean id="myDatasource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="myJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDatasource" />
<property name="jpaVendorAdapter" ref="myJpaVendorAdapter" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
entityManagerFactory bean will use your persistence.xml from classpath to create the persistance unit.
update
get your persistence context like this
#PersistenceContext(unitName="sistema")
protected EntityManager em;
also make sure the class that is using the persistence context is annotated with #Repository
update
can you add this to your web.xml
<!-- The definition of the Root Spring Container shared by all Servlets
and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/WEB-INF/spring-root-context.xml
</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
now create a new file spring-root-context.xml next to spring.xml and move all the DB and transaction related stuff to spring-root-context.xml.
So spring.xml will be your servlet context and spring-root-context.xml will be your root context.
anything related to controllers will go to spring.xml all other beans will go to spring-root-context.xml
also add <context:component-scan base-package="package.for.genericdao" /> to both spring.xml and spring-root-context.xml and replace package.for.genericdao with your base package name.

#ServerEndpoint and Spring MVC injection

I am trying to inject annotated by #Repository class in #ServerEndpoint class. But when i am trying to call repository method it is return null. Another injected bean from this package is working fine.
#ApplicationScoped
#ServerEndpoint("/WebsocketHome/actions")
public class WebSocketServer {
private static final Logger LOG = Logger.getLogger(WebSocketServer.class);
#Inject
private SessionHandler sessionHandler;
#Inject
private PlaceRepository placeRepository;
#OnMessage
public void handleMessage(String message, Session session) {
JSONParser jsonParser = new JSONParser();
try {
JSONObject jsonObject = (JSONObject) jsonParser.parse(message);
if ("getRooms".equals(jsonObject.get("action"))) {
List<Place> places = this.placeRepository.getAllPlaces(); //error is here
}
} catch (ParseException e) {
LOG.error(e.getMessage());
}
.....
This is repository class:
#Repository
#Transactional
public class PlaceRepository {
#Autowired
private SessionFactory sessionFactory;
#SuppressWarnings("unchecked")
public List<Place> getAllPlaces() {
return this.sessionFactory.getCurrentSession().createQuery("from Place place").list();
}
}
web.xml:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<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>
</web-app>
app-context.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: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.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:application.properties" system-properties-mode="ENVIRONMENT"/>
<context:component-scan base-package="com.hms.repository"/>
<context:component-scan base-package="com.hms.utils"/>
<tx:annotation-driven transaction-manager="txManager"/>
<import resource="security-context.xml"/>
<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driverClassName}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<!--
<property name="initialSize" value="5" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
<property name="minIdle" value="2" />
-->
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${db.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hbm2ddl.auto">${db.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
</beans>
Error appears only on calling of #OnMessage method.
All junit #Tests of repository class returns fine results.
What is wrong in my code?
Sorry for my english.
UPD:
It seems, that problem is in SessionFactory dependency because test method, that i add in #Repository:
public String testWS() {
return "Test is ok!";
}
returns fine result.
So, looks like i found the right way. I found it in Spring websocket documentation.
There are some steps what i did:
I put in type-level annotation:
#ServerEndpoint(value = "/WebsocketHome/actions", configurator = SpringConfigurator.class)
I added #Service and #Controller to my websocket classes and "context:component-scan" path to my app-context.xml file so that Spring can find corresponding beans.
I added the "spring-websocket" dependency in my pom.xml (i use maven)
Maybe it is not the right way, but it is works fine for me.
#Today jan 31' 2022 Just Add "spring-websocket" dependency

Spring MVC resource not found on start

So I know there are dozens of posts similar to this, but unfortunately none of those have helped me. I am simply trying to get a demo Spring MVC project up and running. I am trying to run a template project provided by Heroku (https://devcenter.heroku.com/articles/getting-started-with-heroku-eclipse). I have tried many combinations of settings to no avail. Here are the default settings:
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: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_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Spring-Hibernate-Template</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/people/*</url-pattern>
</servlet-mapping>
</web-app>
applicationContext.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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:annotation-config />
<context:component-scan base-package="com.example" />
<mvc:annotation-driven/>
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource"/>
</bean>
<beans profile="default">
<jdbc:embedded-database id="dataSource"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
</beans>
<beans profile="prod">
<bean class="java.net.URI" id="dbUrl">
<constructor-arg value="#{systemEnvironment['DATABASE_URL']}"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="#{ 'jdbc:postgresql://' + #dbUrl.getHost() + ':' + #dbUrl.getPort() + #dbUrl.getPath() }"/>
<property name="username" value="#{ #dbUrl.getUserInfo().split(':')[0] }"/>
<property name="password" value="#{ #dbUrl.getUserInfo().split(':')[1] }"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- change this to 'verify' before running as a production app -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
</beans>
</beans>
PersonController.java:
#Controller
public class PersonController {
#Autowired
private PersonService personService;
#RequestMapping("/")
public String listPeople(Map<String, Object> map) {
map.put("person", new Person());
map.put("peopleList", personService.listPeople());
return "people";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addPerson(#ModelAttribute("person") Person person, BindingResult result) {
personService.addPerson(person);
return "redirect:/people/";
}
#RequestMapping("/delete/{personId}")
public String deletePerson(#PathVariable("personId") Integer personId) {
personService.removePerson(personId);
return "redirect:/people/";
}
}
And I have a 'people.jsp' file at webapp/WEB-INF/jsp/people/jsp
My server.xml context element for the Tomcat server looks like:
<Context docBase="facultypublicationsdb" path="/facultypublicationsdb" reloadable="true" source="org.eclipse.jst.jee.server:facultypublicationsdb"/></Host>
Every time I run this on Tomcat at (http://localhost:8080/facultypublicationsdb/), I get the following:
HTTP Status 404 - /facultypublicationsdb/
type Status report
message /facultypublicationsdb/
description The requested resource (/facultypublicationsdb/) is not available.
Apache Tomcat/7.0.21
I am running this on Ubuntu through eclipse. I notice that no .war is being copied over to the /usr/share/tomcat7/webapps directory. Is that supposed to occur?
Any ideas?
Try checking two things.
First change your web.xml file to map the dispatcher servlet to /. This causes the dispatcher servlet to be used when no other mappings are found for a request, instead of for every request. This is important if you have resources such as CSS and Javascript.
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/people/*</url-pattern>
</servlet-mapping>
Next, if using Eclipse, open your projects properties (Click project in project, explorer Alt+Enter). Then go to deployment assembly. Make sure that all of your projects resources are included here, especially any maven dependencies. If you notice that dependencies are missing click the add button and select them.
You may also want to ensure that your controllers are being picked up by component scanning. Ensure that your controllers are in the com.example package.
I would think you need to specify method = RequestMethod.GET in listPeople method. There could be many small things that could cause 404 error. Could you upload this code on GitHub and I will look into it.

Mixing *-servlet.xml with applicationContext.xml

I have an existing Spring application that does some server side processing. I am trying to create a webapp for this particular application and chose SpringMVC to serve my purpose.
I created a display controller as follows:
#Controller
#RequestMapping("/items")
public class ItemDisplayController {
private static final Logger LOGGER = Logger.getLogger(ItemDisplayController.class);
private static final String ITEMS_REDIRECT = "redirect:/item/items";
#Autowired
private ItemDisplay itemDisplay;
#RequestMapping
public String listItems(ModelMap model) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("List all items");
}
List<ItemDetail> itemDetails = itemDisplay.getAllItems();
model.addAttribute("itemDetails",itemDetails);
return "items";
}
}
I already have an applicationContext file with the following definitions:
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="props" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<array>
<value>classpath:item.properties</value>
<value>file:#{systemEnvironment['ITEM_HOME']}/item.properties</value>
<value>file:#{systemProperties['ITEM_HOME']}/item.properties</value>
</array>
</property>
<property name="ignoreResourceNotFound" value="true"/>
</bean>
<bean id="itemDisplay" class="com.acme.itemDisplayImpl">
<property name="itemDisplayDAO" ref="jdbcItemDisplayDAO"/>
</bean>
<bean id="jdbcItemDisplayDAO" class="com.acme.database.dao.JdbcItemDisplayDAO">
<property name="dataSource" ref = "dataSource"/>
</bean>
<bean id="realDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="#{props['itemds.jdbc.driver']}"/>
<property name="url"><value><![CDATA[#{props['itemds.jdbc.url']}]]></value></property>
<property name="username" value="#{props['itemds.username']}"/>
<property name="password" value="#{props['itemds.password']}"/>
<property name="testOnBorrow" value="#{props['itemds.test.on.borrow']}"/>
<property name="testWhileIdle" value="#{props['itemds.test.while.idle']}"/>
<property name="poolPreparedStatements" value="#{props['itemds.pool.prepared.statements']}"/>
<property name="validationQuery" value="#{props['itemds.validation.query']}"/>
<property name="validationQueryTimeout" value="#{props['itemds.validation.query.timeout']}"/>
<property name="timeBetweenEvictionRunsMillis" value="#{props['itemds.time.between.eviction.runs.millis']}"/>
<property name="maxActive" value="#{props['itemds.max.active']}"/>
<property name="maxIdle" value="#{props['itemds.max.idle']}"/>
<property name="initialSize" value="#{props['itemds.initial.size']}"/>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource" ref="realDataSource"/>
</bean>
</beans>
In my *servlet.xml, I have defined the ViewResolver as follows:
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven/>
<context:annotation-config/>
<context:component-scan base-package="com.acme.item"/>
<bean id="primaryViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="contentType" value="text/html; charset=UTF-8"/>
<property name="order" value="1"/>
</bean>
</beans>
And in the web.xml, I have the context-param defined:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app 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"
xmlns="http://java.sun.com/xml/ns/javaee">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>items</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>items</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
When I run my application, the itemDisplay is not wired up and on the debugger it is showing up with a null value.
Can somebody point out what I may be doing wrong here? In an ideal world, I would assume that annotating the itemDisplay with #Autowired in the controller would help resolve the implementation of the interface.
Only thing I can think of is, ContextLoaderListener does not complain if the applicationContext.xml is not found, Let's try this add classpath*:applicationContext.xml also make sure applicationContext.xml is run time class path of the server
Here is an excellent article that provides a good insight into spring classpath resource.
Your files looks up fine at quick glance. As long as there is only one bean with of ItemDisplay type in your context it should be autowired by type, otherwise you should get error in log file.
One small thing I noticed, which is probably unrelated to your particular issue, is that you map your 'items' controller to all files in web.xml. Usually you would want it to map to particular type of files only - say *.htm so it won't get called for resources such as images etc.
Not sure if this is a typo in your applicationContext file :
<bean id="itemDisplay" class="com.acme.itemDisplayImpl"/>
Shouldn't the class be com.acme.item.DisplayImpl ?. If the name of class is indeed itemDisplayImpl, then you need to change the component-scan element in *servlet.xml to include the correct package.

Categories

Resources