Cannot get Spring MVC to parse date time using DateTimeFormat annotation - java

I want to use a path parameter as a full ISO timestamp in a rest service.
http://domain:8080/ctx/someObj/2000-10-31 01:30:00.000-05:00
I previously had mvc:annotation driven turned on, but turned it off so i could set "useDefaultSuffixPattern" to false on the DefaultAnnotationHandlerMapping.
the controller code
#RequestMapping(value = "/lwc/{userMidnightTime}", method = RequestMethod.GET)
#ResponseBody
public List<ProgramSnippetView> getLiveWebcastsWithin24HoursOfTime(#PathVariable(value = "userMidnightTime") #DateTimeFormat(iso= DATE_TIME) Date userMidnightTime) {
Calendar cal = new GregorianCalendar();
cal.setTime(userMidnightTime);
cal.add(Calendar.HOUR, 24);
Date endTime = cal.getTime();
return programService.getLiveWebcastSnippetsWithProductionDateInRange(userMidnightTime, endTime);
}
I get the following error. I can see that the framework is ultimately calling the deprecated Date.parse() method with the correct String, instead of using joda time to do the work.
112977 [http-apr-8080-exec-7] DEBUG org.springframework.beans.BeanUtils - No property editor [java.util.DateEditor] found for type java.util.Date according to 'Editor' suffix convention
117225 [http-apr-8080-exec-7] DEBUG org.springframework.beans.TypeConverterDelegate - Construction via String failed for type [java.util.Date]
org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [java.util.Date]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException
I want joda to parse the full ISO date, as is specified in the org.springframework.format.annotation.DateTimeFormat.java annotation file like so:
/**
* The most common ISO DateTime Format <code>yyyy-MM-dd'T'hh:mm:ss.SSSZ</code> e.g. 2000-10-31 01:30:00.000-05:00.
* The default if no annotation value is specified.
*/
DATE_TIME, .....
App Context config
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns: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">
<context:component-scan base-package="blah.blah"/>
<mvc:resources mapping="/resources/**" location="/resources/"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatterRegistrars">
<set>
<bean class="org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar">
<property name="useIsoFormat" value="true"/>
</bean>
</set>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="0"/>
<property name="useDefaultSuffixPattern" value="false"/>
<!-- allows for periods in url -->
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator" ref="validator"/>
</bean>
</property>
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<!--<property name="writeAcceptCharset" value="false" />-->
</bean>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="prefixJson" value="true"/>
</bean>
</list>
</property>
</bean>
<mvc:view-controller path="/" view-name="home"/>

One possible issue that I see is that you have not registered conversionService with handlerAdapter, you can do it this way:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="conversionService" ref="conversionService"/>
<property name="validator" ref="validator"/>
</bean>
</property>

This is way too late (3 years, precisely), but it may help someone else.
The url is missing the time designator 'T', so try
http://domain:8080/ctx/someObj/2000-10-31T01:30:00.000-05:00
instead of
http://domain:8080/ctx/someObj/2000-10-31 01:30:00.000-05:00

Related

How correctly configure transaction manager in Spring?

Im trying to save the data into PostgreSQL database, I configure my dataSource bean:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost/testdb"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
<!-- <property name="initialSize" value="5"/>-->
<!-- <property name="maxActive" value="10"/>-->
</bean>
then insert them into sessionFactory
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>com.nazik.domain</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.PostgreSQL10Dialect</prop>
</props>
</property>
</bean>
and configure transactionManager
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
but when I start transaction using code:
#Override
public void createPerson(final Person person) {
transactionTemplate.execute(new TransactionCallback<Void>() {
public Void doInTransaction(TransactionStatus transactionStatus){
try{
createPerson(person);
}catch (RuntimeException e){
transactionStatus.setRollbackOnly();
throw e;
}
return null;
}
});
}
i have got an error:
Exception in thread "main" org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'transactionManager' is expected to be of type 'org.hibernate.SessionFactory' but was actually of type 'org.springframework.orm.hibernate5.HibernateTransactionManager'
at org.springframework.beans.factory.support.AbstractBeanFactory.adaptBeanInstance(AbstractBeanFactory.java:417)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:398)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1160)
please explain me what am I doing wrong
I'm not completely sure since I have no way to test but at least the exception says that the configuration of 'transaction manager' receives the wrong type of parameter.
you can test this way.
<bean id = "transactionManager"
class = "org.hibernate.SessionFactory">
<property name = "sessionFactory" ref = "sessionFactory" />
</bean>
You can try to see if it is that, I leave you as an answer since I can not comment yet.
Pdt: as a personal recommendation I suggest you use JPA since it has a simpler handling of transactions
I could test this on similar setup and configuration except I am using HibernateTemplate. Since you are using Hibernate - you should be generally using HibernateTemplate or even better JPA APIs ( which can be used as Hibernate underlying JPA implementation)
You can also use #Transactional annotation rather than programatically defining your boundaries and exception handling.
My sample configuration looks like this
<?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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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
">
<tx:annotation-driven />
<context:component-scan base-package="springmvc"></context:component-scan>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
name="viewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
name="ds">
<property name="driverClassName"
value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/springjdbc" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
name="sessionFactory">
<property name="dataSource" ref="ds" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>springmvc.model.User</value>
</list>
</property>
</bean>
<bean class="org.springframework.orm.hibernate5.HibernateTemplate"
name="hibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean
class="org.springframework.orm.hibernate5.HibernateTransactionManager"
name="transactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>
And my data saving code looks like this
#Autowired
private HibernateTemplate hibernateTemplate;
#Transactional
public int saveUser(User user) {
int id = (Integer)this.hibernateTemplate.save(user);
return id;
}
And I can save data in database ( MySQL in my case but that is irrelevant here)

Dispacter Servelt xml file

I am working on project with Spring mvc and i want to use jpa features as well.
I have an 3 entity classes, their corresponding repository interfaces. I have their autowired objects in common service class. However I am facing issues while creating bean for this service class object which is used in controller.
The 3 model class are User, Appointment and Notification.
The repository interface extends CRUDRepository interface.
Service class :
#Service
public class EHealthService
{
#Autowired
UserRepository uRepo;
#Autowired
AppointmentRepository aRepo;
#Autowired
NotificationRepository nRepo;
public void registerUser(User u)
{
uRepo.save(u);
}
public boolean login(User u)
{
if(uRepo.findByemail(u.getEmail())!=null)
return true;
else
return false;
}
public List<User> getDoctorList()
{
return uRepo.findByisdoctor(true);
}
// some more functions
}
Controller class:
#Controller
public class EHealthController
{
#Autowired
EHealthService eservice;
//Some code
}
ehealth-dispacter-servlet.xml file:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<context:component-scan base-package="com.cl3.controller" />
<context:component-scan base-package="com.cl3.model" />
<context:component-scan base-package="com.cl3.service" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="packagesToScan" value="com.cl3.model"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<jpa:repositories base-package="com.cl3.model"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/cl3" />
<property name="username" value="ucan" />
<property name="password" value="ucan" />
</bean>
<bean id="eservice" class="com.cl3.service.EHealthService">
<property name="uRepo" ref="uRepo"></property>
<property name="nRepo" ref="nRepo"></property>
<property name="aRepo" ref="aRepo"></property>
</bean>
<bean id="uRepo" class="com.cl3.model.UserRepository">
</bean>
<bean id="nRepo" class="com.cl3.model.NotificationRepository">
</bean>
<bean id="aRepo" class="com.cl3.model.AppointmentRepository">
</bean>
It says the class is an interface.
What will be the bean for eservice object and to enable jpa in dispacter servel xml file?
Thank you.
If you are using spring xml based configuration then add below bean's to configuration file :
<bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- This makes /META-INF/persistence.xml is no longer necessary -->
<property name="packagesToScan" value="com.howtodoinjava.demo.model" />
<!-- JpaVendorAdapter implementation for Hibernate EntityManager.
Exposes Hibernate's persistence provider and EntityManager extension interface -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="password" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryBean" />
Register component scanning by adding this binding annotation in xml file :
<context:component-scan base-package="com.mycompany.projectname.demo" />
If your project is spring mvc the add below binding annotation to xl file
<!-- This allow for dispatching requests to Controllers -->
<mvc:annotation-driven />
For declarative transaction management add below piece in xml file.
<tx:annotation-driven />
Basically you no need to add service bean in xml configuration file if you are enabled component scanning feature in spring.
Add required dependencies to integrate jpa with spring.
Refer this link will help you more :
https://howtodoinjava.com/jpa/spring-hibernate-jpa-configuration-example/

JPA Hibernate Spring MySql Tomcat - Connect to 2 databases

I've been searching, reading, trying code for 2 days and have not been successful.
I need to be able to connect to 2 different databases, not necessarily simultaneously, using the technologies listed in the header. I'm using Tomcat7, not a J2EE container.
Below is what I have for the application context. It works fine for one database. What do I need to do to configure it for two? How do I tell my DAOs which connection to use? Thanks in advance.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<tx:annotation-driven/>
<context:component-scan base-package="org.aaa.slds"/>
<context:property-placeholder location="classpath:db.properties" />
<bean id="dataSourceWCCC" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="username" value="${dbuser_wccc}"/>
<property name="password" value="${dbpassword_wccc}"/>
<property name="url" value="${dburl_wccc}"/>
<property name="driverClassName" value="${dbdriver_wccc}"/>
</bean>
<bean id="dataSourceDWS" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="username" value="${dbuser_dws}"/>
<property name="password" value="${dbpassword_dws}"/>
<property name="url" value="${dburl_dws}"/>
<property name="driverClassName" value="${dbdriver_dws}"/>
</bean>
<bean id="entityManagerFactoryWCCC" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSourceWCCC"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<map>
<entry key="hibernate.hbm2ddl.auto" value="create-drop"/>
<entry key="hibernate.show_sql" value="false"/>
</map>
</property>
<property name="packagesToScan" value="org.aaa.slds.core.models.entities.wccc"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"/>
As soon as I add a 2nd EntityManager I get a runtime errpr ///
INFO: HHH000204: Processing PersistenceUnitInfo [
name: punit2
...]
May 18, 2015 1:01:22 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
Here is my complete appcontext file ...
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<!-- Enable AspectJ style of Spring AOP -->
<aop:aspectj-autoproxy/>
<context:annotation-config/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<context:component-scan base-package="gov.wyo.slds"/>
<!-- Configure Aspect Beans, without this Aspects advices won't execute
<bean name="loggingAspect" class="LoggingAspect" /> -->
<bean id="dataSourceWCCC" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="${wccc.dbuser}"/>
<property name="password" value="${wccc.dbpassword}"/>
<property name="url" value="${wccc.dburl}"/>
<property name="driverClassName" value="${wccc.dbdriver}"/>
</bean>
<bean id="entityManagerFactoryWCCC" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="punit"/>
<property name="dataSource" ref="dataSourceWCCC"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"/>
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<entry key="hibernate.hbm2ddl.auto" value="update"/>
<entry key="hibernate.format_sql" value="true"/>
</map>
</property>
<property name="packagesToScan" value="gov.wyo.slds.core.models.entities.wccc"/>
</bean>
<bean id="dataSourceDWS" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="${dws.dbuser}"/>
<property name="password" value="${dws.dbpassword}"/>
<property name="url" value="${dws.dburl}"/>
<property name="driverClassName" value="${dws.dbdriver}"/>
</bean>
<bean id="entityManagerFactoryDWS" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="punit2"/>
<property name="dataSource" ref="dataSourceDWS"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"/>
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<entry key="hibernate.hbm2ddl.auto" value="create"/>
<entry key="hibernate.format_sql" value="true"/>
</map>
</property>
<property name="packagesToScan" value="gov.wyo.slds.core.models.entities.dws"/>
</bean>
<bean id="transactionManagerWCCC" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryWCCC" />
<qualifier value="wccc"/>
</bean>
<bean id="transactionManagerDWS" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryDWS" />
<qualifier value="dws"/>
</bean>
<tx:annotation-driven/>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- TODO: re-eanble when we have services -->
<!-- context:component-scan base-package="com.slds.core.services.impl"/> -->
And here is my persistence.xml
<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.1">
<persistence-unit name="punit">
</persistence-unit>
<persistence-unit name="punit2">
</persistence-unit>
A more complete error is
Error creating bean with name 'DWSWageControllerImpl' defined in file [/Users/sja/Development/p20w-slds-poc/target/slds-1.0-SNAPSHOT/WEB-INF/classes/gov/wyo/slds/api/controllers/impl/DWSWageControllerImpl.class]
Unsatisfied dependency expressed through constructor argument with index 0 of type [gov.wyo.slds.core.services.DWSWageService]: :
Error creating bean with name 'DWSWageService':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private gov.wyo.slds.core.repositories.wccc.DWSWageRepository gov.wyo.slds.core.services.impl.DWSWageServiceImpl.dwsWageRepository;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'dwsWageRepository':
Injection of persistence dependencies failed;
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined:
expected single matching bean but found 2:
entityManagerFactoryWCCC,entityManagerFactoryDWS;
Any help would be appreciated.
For that you need to have:
Two EntityManagerFactory:
<bean id="entityManagerFactoryWCCC" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSourceWCCC"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<map>
<entry key="hibernate.hbm2ddl.auto" value="create-drop"/>
<entry key="hibernate.show_sql" value="false"/>
</map>
</property>
<property name="packagesToScan" value="org.aaa.slds.core.models.entities.wccc"/>
</bean>
<bean id="entityManagerFactoryDWS" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSourceDWS"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<map>
<entry key="hibernate.hbm2ddl.auto" value="create-drop"/>
<entry key="hibernate.show_sql" value="false"/>
</map>
</property>
<property name="packagesToScan" value="org.aaa.slds.core.models.entities.dws"/>
</bean>
Two JPA transaction managers:
<bean id="transactionManagerWCCC" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryWCCC" />
<qualifier value="wccc"/>
</bean>
<bean id="transactionManagerDWS" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryDWS" />
<qualifier value="dws"/>
</bean>
And your Service methods are annotated for a specific transaction manager:
#Transactional("wccc")
or
#Transactional("dws")
If you want to enlist both data sources in a global transaction, you need to use JTA transactions and a JTA transaction manager.

How to use Spring's i18n mechanism?

I added localization to my Spring project and it appears to be working but I wonder how I change the language, if the language choice is done based on the browser setting, the HTTP header, a cookie or something else. Is there a way to be explicit as well e.g. taking the locale as a parameter in a way like e.g. hl=de on the HTTP query string? I also want to allow the user to set the language on a settings page, how can I do that? My implementation looks like this and writes messages in English:
<h4 class="title"><fmt:message key="login.title"/></h4>
servlet.xml:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
So how can I
a) Make the locale choice explicit by enabling overriding the locale with a HTTP GET parameter such as hl=de for German and hl=fr for French?
b) Let a user choose locale?
Update
The interceptor is not working. The XML is:
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="sv" />
</bean>
<mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
</mvc:interceptors>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="100000"/>
</bean>
</beans>
a) you defined a bean with id localeChangeInterceptor:
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
this interceptor enable you to change your locale using the param you choose (in this case: "lang") in your query string (ie: http://mydomain.com/mypage?lang=fr for french)
b) you can provide users link for changing locale using point a)
c) you selected a default locale: "en". otherwhise locale is choosen using browser language
NOTE: you should use <spring:message code="${msg.value}" arguments="${msg.args}"/>for your localized string, not fmt, for more integration with spring...
You already have configured the LocaleChangeInterceptor. Its parameter paramName (you set it to lang) is the request parameter that changed the locale.
change the configuration to hl, then you can use this parameter to change it:
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="hl" />
</bean>
to let the user change the local, you only need to add some link to the page
German
#See JavaDoc: LocalChangeInterceptor#setParamName

Validate format parameter via config in Spring MVC

Here is my situation:
I have my mvc-config.xml file for my web service set up to have JSON as the default media type. I also have favorParameter for the ContentNegotiatingViewResolver as true. Additionally, I have useNotAcceptableStatusCode as true so that not accepted formats will return a 406.
My question is: Is there a way, in the config, to trigger the 406 status code when someone passes in an unacceptable format parameter (format=foo)? Or must that be done with code?
Here is the config file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
<property name="defaultViews">
<list>
<bean class="com.work.stuff.web.view.json.ExtendedMappingJacksonJsonView">
<property name="objectMapper">
<ref bean="JacksonObjectMapper" />
</property>
</bean>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<property name="marshaller">
<ref bean="Jaxb2Marshaller" />
</property>
</bean>
</list>
</property>
<property name="defaultContentType" value="application/json" />
<property name="favorParameter" value="true" />
<property name="useNotAcceptableStatusCode" value="true" />
</bean>
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<ref bean="JacksonObjectMapper" />
</property>
</bean>
<ref bean="marshallingHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="marshallingHttpMessageConverter"
class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="Jaxb2Marshaller" />
<property name="unmarshaller" ref="Jaxb2Marshaller" />
</bean>
<bean id="JacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
<bean id="JacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig"
factory-bean="JacksonObjectMapper" factory-method="getSerializationConfig" />
<bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="JacksonSerializationConfig" />
<property name="targetMethod" value="setSerializationInclusion" />
<property name="arguments">
<list>
<value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_NULL</value>
</list>
</property>
</bean>
<bean id="Jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.work.stuff.Concepts</value>
<value>com.work.stuff.Concept</value>
<value>com.work.stuff.Terms</value>
<value>com.work.stuff.Term</value>
<value>com.work.stuff.Namespaces</value>
<value>com.work.stuff.Namespace</value>
<value>com.work.stuff.Subsets</value>
<value>com.work.stuff.Subset</value>
<value>com.work.stuff.Associations</value>
<value>com.work.stuff.Association</value>
</list>
</property>
</bean>
</beans>
ContentNegotiatingViewResolver doesn't seem to support such behaviour. For now, I think your best bet is to subclass it and override the getMediaTypeFromParameter() method to throw an exception if the media type is not supported.
You can throw any RuntimeException from that method, and if you annotate the exception class with #ResponseStatus, you can control the HTTP response code, e.g.
#ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
public class FormatNotSupportedException extends RuntimeException {
}
In the longer term, I strongly encourage you to file an issue with http://jira.springsource.org, asking for such functionality to be added to ContentNegotiatingViewResolver. They should be able to add this as an optional behavioural parameter. It's requests like these that mean Spring keeps getting better.

Categories