I was trying to access database using jdbcdao as per the following example:
http://www.mkyong.com/spring/spring-jdbctemplate-jdbcdaosupport-examples/
userdao, userdaoimpl,daocontext and datacontext.xml are as follows:
DAOIMPL
public class UserDAOImpl extends JdbcDaoSupport implements UserDAO {
/*Creates User */
public void insertUser(User user){
String sql = "INSERT INTO Users " +
"(id, username, password,role) VALUES (?, ?, ?,?)";
getJdbcTemplate().update(sql, new Object[] { user.getUserId(),
user.getUserName(),user.getPassWord()
});
}
}
DAO
import java.util.List;
import spring.web.models.User;
public interface UserDAO {
public void insertUser(User user);
}
DAOCONTEXT.XML
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="userDAO" class="spring.web.dao.impl.UserDAOImpl">
<property name="primaryDataSource" ref="oracleDataSource" />
</bean>
</beans>
DATA-CONTEXT.XML
<?xml version="1.0"?>
<beans
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans">
<bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property value="oracle.jdbc.OracleDriver" name="driverClassName" />
<property value="jdbc:oracle:thin:#192.168.72.68:1521:d2he"
name="url" />
<property value="aaryal_1" name="username" />
<property value="oracle" name="password" />
</bean>
</beans>
The error I am facing is as follows:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDAO' defined in class path resource [dao-context.xml]:
Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException:
Invalid property 'primaryDataSource' of bean class [spring.web.dao.impl.UserDAOImpl]:
Bean property 'primaryDataSource' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the getter?
Please suggest me what did I miss.
You need a setPrimaryDataSource method in UserDAOImpl class. The error says it all. It's expecting a property called primaryDataSource in your class, but can't find it. Hence the error.
You'll need to do this:
private DataSource dataSource;
public void setPrimaryDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
EDIT:
If you go through the API of JdbcDaoSupport, the setDataSource method already exists. So to solve your error, you can either do the above, or simply rename your DataSource bean name to dataSource
Related
I have my datasource in below class. Is there any way I can use that in config.xml?
I am getting an Error creating bean with name 'cmsTemplate' defined in file: cannot resolve reference bean 'contentDataSource' while setting constructor argument.
JdbcConfiguration.java
#Configuration
public class JdbcConfiguration{
#Value("$comContent.url")
private String dbUrl;
#Value("$comContent.dbUser")
private String dbUser;
#Value("$comContent.dbPass")
private String dbPass;
//rest of the properties
#Bean
#Primary
public DataSource contentDataSource() throws SQLException {
//code
}
}
config.xml
<bean id="cmsTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-args type="javax.sql.DataSource">
<ref bean="contentDataSource"/>
</constructor-args>
<property name="fetchSize" value="{systemProperties['jdbcFetchSize']}" />
</bean>
//Need to create datasource before spring context is getting created. Previously it was like below commented code.
<!-- <bean id="contentDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/comContent</value>
</property>
</bean> -->
I have controller
#Controller
public class AuthorController {
#Autowired
private AuthorDAO authorDao;
#RequestMapping("/authors")
public String showAuthor(#RequestParam String name, ModelMap model) {
Author author = authorDao.findByName(name);
model.addAttribute("author", author);
return "authors";
}
}
I wrote test for it
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:test-application-context.xml"})
public class AuthorControllerTest {
private static final String JACK_C = "Jack C.";
#Autowired
AuthorController controller;
#Test
public void testShowAuthor() {
Author expectedAuthor = new Author();
AuthorDAO daoMock = mock(AuthorDAO.class);
when(daoMock.findByName(JACK_C)).thenReturn(expectedAuthor);
ModelMap model = new ModelMap();
String view = controller.showAuthor(JACK_C, model);
assertEquals("View name is incorrect","authors", view);
assertSame(expectedAuthor, model.get("author"));
verify(daoMock).findByName(JACK_C);
}
}
test-application-context.xml:
<context:annotation-config />
<context:component-scan base-package="com.github.futu" />
<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/blog" /> <property name="username"
value="blogger" /> <property name="password" value="blogger" /> </bean>
<bean id="com.github.futu.dao.AuthorDAO" class="com.github.futu.dao.impl.AuthorDAOXml"/>
<bean id="com.github.futu.dao.PostDAO" class="com.github.futu.dao.impl.PostDAOXml" />
<bean id="validator" class="com.github.futu.validator.PostValidator" />
But real dao is called. What have I missed?
You're creating a mock here
AuthorDAO daoMock = mock(AuthorDAO.class);
that is completely unrelated to your controller injected into your test class
#Autowired
AuthorController controller;
Of course the autowired AuthorDao target is going to come from your XML configuration
#Autowired
private AuthorDAO authorDao;
Ideally you would change your XML configuration only produce a #Controller bean and add a setter to it to set the AuthorDao from within the test, using your mock.
once again iam looking a for help/guide from experts,
My problem is, i need to create Dynamic web site which calls to restfull server to get data, all the requests are POST and returns json object. Iam thinking of use of Spring RestTemplate to make calls to server. My Server works ok, meaning currently some android and Apple apps connects to same APIs and they work ok. But when i try to use RestTemplate to connect to server, it gives some errors
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
this is my server,
#Controller
public class ABCController
{
#RequestMapping(method = RequestMethod.POST, value = "/user/authenticate")
public #ResponseBody LoginResponse login(#RequestParam("email") String email,#RequestParam("password") String password,#RequestParam("facebookId") String facebookId) {
LoginRequest request = new LoginRequest(email, password, facebookId);
UserBusiness userBusiness = UserBusinessImpl.getInstance();
return userBusiness.login(request);
}
}
And this is my spring configs of server,
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean id="jsonViewResolver" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
<bean name="abcController" class="com.abc.def.controller.ABCController" />
<mvc:annotation-driven />
</beans>
This is how i try to call the server using RestTemplate,
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<!-- <constructor-arg ref="httpClientFactory"/> -->
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<ref bean="JacksonObjectMapper" />
</property>
</bean>
</list>
</property>
</bean>
<bean id="JacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
and this is how i use it (for testing)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("root-context.xml");
RestTemplate twitter = applicationContext.getBean("restTemplate", RestTemplate.class);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("email", "x1#test.com");
map.add("password", "abc");
map.add("facebookId", null);
HttpEntity<LoginResponse> response= twitter.exchange("https://abc.com/Rest/api/user/authenticate", HttpMethod.POST, map, LoginResponse.class);
my login response class, and its sub classes,
LoginResponse
public class LoginResponse extends BaseResponse {
private LoginBase data;
with getters and setters
}
Login Base
public class LoginBase {
private String token;
private User user;
with getters and setters
}
User
public class User {
private Integer userId;
private String email;
private Integer status;
private String name;
with getters and setters
}
finally BaseResponse
public class BaseResponse {
protected String statusCode;
with getter and setter }
My questions are,
1. Why do i get this error when i call the server
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#63de8f2d: defining beans [restTemplate,JacksonObjectMapper]; root of factory hierarchy
WARN : org.springframework.web.client.RestTemplate - POST request for "https://abc.com/Rest/api/user/authenticate" resulted in 400 (Bad Request); invoking error handler
Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:90)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:494)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:451)
2. how do i map json response to java LoginResponse
You might have to add the content-type and accept headers to your request.
Mapping the response to LoginResponse can be done directly like this
LoginResponse lResponse = response.getBody();
or If you are using restTemplate.postForObject(), the reponse will be in the form of LoginResponse
I am using seam with tomcate and icefaces the problem is when I inject entity manager in component bean it works well but if put it in generic DAO it returns null my code is like that:
this the bean
#Scope(ScopeType.PAGE)
#Name("TestBean")
public class TestBean {
public void test(ActionEvent actionEvent) {
Roles entity = new Roles();
entity.setName("cons");
RolesDao dao = new RolesDao();
dao.emPrisit(entity);
}
}
DAO
public class RolesDao {
#In
EntityManager em;
public void emPrisit(Roles entity) {
em.persist(entity);
}
}
Component.xml
<persistence:entity-manager-factory name="bookingDatabase"/>
<persistence:managed-persistence-context name="em"
auto-create="true"
entity-manager-factory="#{bookingDatabase}"/>
persistence.xml
<persistence-unit name="bookingDatabase"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence </provider>
<jta-data-source>java:comp/env/AP</jta-data-source>
<properties>
<property name="transaction.flush_before_completion" value="true" />
<property name="transaction.factory_class"
value="org.hibernate.transaction.JDBCTransactionFactory" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<!--
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
-->
</properties>
</persistence-unit>
if I inject entitymanger in bean not dao it runs well the second problem when I add this annotation before entitymanger
#In
#PersistenceContext(type = PersistenceContextType.EXTENDED)
EntityManager em;
it give this exception
caused by: java.lang.IllegalArgumentException: #PersistenceContext may only be used on session bean or message driven bean components: TestBean
at org.jboss.seam.Component.checkPersistenceContextForComponentType(Component.java:901)
at org.jboss.seam.Component.scanField(Component.java:877)
at org.jboss.seam.Component.initMembers(Component.java:557)
at org.jboss.seam.Component.<init>(Component.java:244)
at org.jboss.seam.Component.<init>(Component.java:205)
at org.jboss.seam.init.Initialization.addComponent(Initialization.java:1186)
... 13 more
You don't need both #In and #PersistenceContext on your EntityManager. It is enough with one of them.
Injection only occurs in Beans, so your DAO should have a #Name("something"), otherwise Seam doesn't knows what to do with your class.
#Name("RolesDao")
public class RolesDao {
#In
EntityManager em;
public void emPrisit(Roles entity) {
em.persist(entity);
}
}
Then to use this class you should either do:
#In(value="RolesDao") // value="..." is optional
private RolesDao rolesDao;
or
org.jboss.seam.Component.getInstance(RolesDao.class)
Sorry if the sample code has some errors, didn't had eclipse to try it.
Hope this helps
I have been trying out the new Spring MVC 3.0 Type Conversion Framework. I cannot find out how to trap conversion errors.
I am using the new mvc schema:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!-- Scan this package and sub-packages for Annotated Controllers -->
<context:component-scan base-package="springmvc.simple"/>
<!-- New Spring 3.0 tag to enable new Converter and Formatting Frameworks -->
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
And a simple command class:
public class Amount {
#NumberFormat(style=Style.CURRENCY)
#Min(0)
private BigDecimal amount = BigDecimal.valueOf(10000, 2);
#DateTimeFormat(iso=ISO.DATE)
private Date date = new Date();
public Date getDate() {
return date;
}
public BigDecimal getAmount() {
return amount;
}
}
And an equally simple controller:
#Controller
#RequestMapping(value="/addVat.html")
public class AddVatController {
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.initDirectFieldAccess();
}
#RequestMapping(method = RequestMethod.GET)
public String setupForm(Model model) {
model.addAttribute("commandBean", new Amount());
return "addVatForm";
}
#RequestMapping(method = RequestMethod.POST)
public String onSubmit(#ModelAttribute("commandBean") #Valid Amount commandBean, BindingResult amountBinding, Model model) {
if (amountBinding.hasErrors()) {
return "addVatForm";
}
BigDecimal result = commandBean.getAmount().multiply(new BigDecimal("1.175"));
model.addAttribute("result", result);
return "result";
}
}
This works fine - I get validation error in my result.jsp if I enter a negative value for the BigDecimal. However if I try to send a Date such as 2010-07-024, which does not conform to ####-##-##, I get an error:
org.springframework.core.convert.ConversionFailedException: Unable to convert value 2010-07-024 from type 'java.lang.String' to type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value 2010-07-024 from type 'java.lang.String' to type 'java.util.Date'; nested exception is java.lang.IllegalArgumentException: Invalid format: "2010-07-024" is malformed at "4"
org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:135)
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:199)
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:169)
org.springframework.beans.DirectFieldAccessor.setPropertyValue(DirectFieldAccessor.java:125)
org.springframework.beans.AbstractPropertyAccessor.setPropertyValue(AbstractPropertyAccessor.java:50)
org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:665)
org.springframework.validation.DataBinder.doBind(DataBinder.java:561)
org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:190)
org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:110)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.doBind(AnnotationMethodHandlerAdapter.java:696)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:744)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:296)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:163)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:563)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Which is fine - but how do I trap the error? I was expecting BindingResult to simply contain another error?
See if registering appropriate DateEditor can help you..... 15.3.2.12
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.initDirectFieldAccess();
**/* register appropriate date editor */**
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
According to Juergen Hoeller, this was fixed in Spring 3.0.2