Spring 3 -- NullPointerException from JDBCTemplate.getQueryForMap() - spring

I am running a custom tag in a Spring JSP. I am getting the following error message.
java.lang.NullPointerException
com.dao.Poll1DAO.getVotes(Poll1DAO.java:27)
com.tags.Poll1Tag.doTag(Poll1Tag.java:23)
org.apache.jsp.WEB_002dINF.pages.PollPage_jsp._jspx_meth_myTag1_005fpoll1_005f0(PollPage_jsp.java:602)
org.apache.jsp.WEB_002dINF.pages.PollPage_jsp._jspService(PollPage_jsp.java:195)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1265)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1016)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:965)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:859)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:883)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:781)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
Here is Poll1DAO.getVotes().
public HashMap<String, Object> getVotes() {
// following line is line 27, referenced in error message
return (HashMap<String, Object>) this.getJdbcTemplate().queryForMap(
"select yes, no from poll1 where id = 1");
}
Here is Poll1Tag.doTag().
Poll1DAO poll1DAO = new Poll1DAO();
public void doTag() throws JspException, IOException {
PageContext pageContext = (PageContext) getJspContext();
boolean foundCookie = cookieFound();
pageContext.setAttribute("foundCookiePoll1", foundCookie);
if (foundCookie) {
// following line is line 23, referenced in error message
HashMap<String, Object> poll1Votes = poll1DAO.getVotes();
pageContext.setAttribute("poll1Yes", (int) poll1Votes.get("yes"));
pageContext.setAttribute("poll1No", (int) poll1Votes.get("no"));
}
}

If you are using IoC container such as Spring's application context you should never create managed bean instances by yourself. You always need to pull the instance out from the container - i.e. ApplicationContext. Otherwise they will not be initalized with the necessary dependencies.
Now the question you should ask is - how can I get ApplicationContext instance in a JSP tag class. The answer is simple - just look how the standard Spring tags are doing that (I mean that - go check that link).
// Example on how to obtain bean from JSP tag (ignoring context hierarchy)
WebApplicationContextUtils.getRequiredWebApplicationContext(pageContext.getServletContext()).
getBeansOfType(Poll1DAO.class).values().iterator().next();

Related

Spring Boot replacing application property on startup

In my Spring Boot application I need to replace some properties defined in application.yml with the ones from AWS Secrets Manager. I am aware of Spring Cloud AWS Secrets Manager project, but for various reasons using it is not an option for me. I decided implement a listener which would listen to ApplicationEnvironmentPreparedEvent and replace all the properties I need. The problem is that I am getting a strange exception which I cannot explain. Here is my code (It is a bit messy since I experimented with it.
I know by experimenting that the PropertySource of application.yml is always instance of MapPropertySource
Replacing property within PropertySource is not an option since the map within it is immutable, I need to replace the entire PropertySource with a new one containing modified properties
The properties within PropertySource map are instances of OriginTrackedValue, so I need to construct them
#Component
#Slf4j
public class PropertiesListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
#Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
Iterator<PropertySource<?>> iterator = propertySources.iterator();
while (iterator.hasNext()) {
PropertySource<?> propertySource = iterator.next();
PropertySource<?> replacement = replaceWithSecrets(propertySource);
if (replacement != null) {
propertySources.remove(propertySource.getName());
propertySources.addLast(replacement);
}
}
}
private PropertySource<?> replaceWithSecrets(PropertySource<?> originalPropertySource) {
boolean needsReplacement = false;
Map<String, Object> newMap = new HashMap<>();
MapPropertySource map = null;
if (originalPropertySource instanceof MapPropertySource) {
map = (MapPropertySource) originalPropertySource;
for (Map.Entry<String, Object> entry : map.getSource().entrySet()) {
if (needsReplacement(entry.getValue().toString())) {
Origin origin = OriginLookup.getOrigin(originalPropertySource, entry.getKey());
OriginTrackedValue val = OriginTrackedValue.of(replaceWithSecret(entry.getValue().toString()), origin);
newMap.put(entry.getKey(), val);
needsReplacement = true;
} else {
newMap.put(entry.getKey(), entry.getValue());
}
}
if (needsReplacement) {
return new MapPropertySource(originalPropertySource.getName(), Collections.unmodifiableMap(newMap));
} else {
return null;
}
}
On startup my application throws an exception
12:51:25.523 [main] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration]; nested exception is java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration$JpaWebConfiguration
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:610)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:311)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250)
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:600)
at org.springframework.context.annotation.ConfigurationClassParser.access$800(ConfigurationClassParser.java:111)
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.lambda$processGroupImports$1(ConfigurationClassParser.java:812)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:809)
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:780)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:193)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:326)
at com.ewc.inventory.EwcInventoryApplication.main(EwcInventoryApplication.java:24)
Caused by: java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration$JpaWebConfiguration
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60)
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:226)
at org.springframework.context.annotation.ConfigurationClassParser.processMemberClasses(ConfigurationClassParser.java:372)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:272)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250)
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:600)
... 21 common frames omitted
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.boot.origin.OriginTrackedValue] to type [java.lang.String]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175)
at org.springframework.core.env.AbstractPropertyResolver.convertValueIfNecessary(AbstractPropertyResolver.java:265)
at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:91)
at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:62)
at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:588)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition$Spec.collectProperties(OnPropertyCondition.java:140)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition$Spec.access$000(OnPropertyCondition.java:105)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.determineOutcome(OnPropertyCondition.java:91)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.getMatchOutcome(OnPropertyCondition.java:55)
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
... 27 common frames omitted
The root cause seems to be
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.boot.origin.OriginTrackedValue] to type [java.lang.String]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322)
I tried to change the code around, by adding the string directly to PropertySource map instead of OriginTrackedValue, construct OriginTrackedValue in different way, but I am still getting the same exception. I am getting it even if I construct new MapPropertySource with the map from old property source.

Unable to load the spring beans inside the webapplication

I am having a helper class inside my web application which is responsible to invoke a method on a spring bean.
Below is the class definition:
package org.learning.spring.remoting;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ClientInvoker {
public static int sum(int a, int b) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:client-beans.xml");
Calculation calculation = (Calculation) context.getBean("calculationBean");
return calculation.add(a, b);
}
}
Inside my jsp below is the code which invokes the function on ClienInvoker
<%#page import="org.learning.spring.remoting.ClientInvoker"%>
<%
int a=Integer.parseInt(request.getParameter("number"));
int b=Integer.parseInt(request.getParameter("number"));
out.print("cube of "+ClientInvoker.sum(a, b));
%>
When I run the web application, I am getting the below exception:
org.apache.jasper.JasperException: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [client-beans.xml]; nested exception is java.io.FileNotFoundException: class path resource [client-beans.xml] cannot be opened because it does not exist
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:555)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Basically, its not loading the client-beans.xml file which I have placed under the WEB-INF directory.
Can someone let me know where I am going wrong.

Jooq, Spring, And BoneCP connection closed twice error

I am using Spring 4.0.0, along with jOOQ 3.2.0 and BoneCP 0.8.0 for a web application.
I have the PersistenceContext configured the same as this guide (please skim read it's a little too much code to paste here)
http://www.petrikainulainen.net/programming/jooq/using-jooq-with-spring-configuration/
but with a smaller number of max connections and closeConnectionWatch = true for error checking.
From what I can deduce, this guide is a non-XML version of the jOOQ website's own guide seen here
http://www.jooq.org/doc/3.2/manual/getting-started/tutorials/jooq-with-spring/
My problem comes from probably not knowing how to use the jOOQ generated DAOs or the #Transactional annotation. I am coming across loads of "connection closed twice" exceptions, which makes my application fundamentally broken. The following stack trace doesn't actually say it is closed twice, but the output of closeConnectionWatch says something along the lines of
bonecp connection closed twice detected: first location connection was closed in thread[blah]
closed again in thread[blah2]
Stack trace of SQL Exception after the connection watch does its thing:
Jan 28, 2014 10:51:51 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/application] threw exception [Request processing failed; nested exception is org.springframework.jdbc.UncategorizedSQLException: jOOQ; uncategorized SQLException for SQL
<snip> error code [0]; Connection is closed!; nested exception is java.sql.SQLException: Connection is closed!] with root cause java.sql.SQLException: Connection is closed!
at com.jolbox.bonecp.ConnectionHandle.checkClosed(ConnectionHandle.java:459)
at com.jolbox.bonecp.ConnectionHandle.prepareStatement(ConnectionHandle.java:1011)
at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.invoke(LazyConnectionDataSourceProxy.java:376)
at com.sun.proxy.$Proxy73.prepareStatement(Unknown Source)
at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:240)
at com.sun.proxy.$Proxy73.prepareStatement(Unknown Source)
at org.jooq.impl.ProviderEnabledConnection.prepareStatement(ProviderEnabledConnection.java:112)
at org.jooq.impl.SettingsEnabledConnection.prepareStatement(SettingsEnabledConnection.java:76)
at org.jooq.impl.AbstractResultQuery.prepare(AbstractResultQuery.java:224)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:295)
at org.jooq.impl.AbstractResultQuery.fetch(AbstractResultQuery.java:324)
at org.jooq.impl.SelectImpl.fetch(SelectImpl.java:1034)
at org.jooq.impl.DAOImpl.fetch(DAOImpl.java:249)
----> at com.myapplication.spring.services.UserService.authenticate(UserService.java:32)
at com.myapplication.spring.controllers.LoginController.doLogin(LoginController.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:833)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.github.dandelion.datatables.core.web.filter.DatatablesFilter.doFilter(DatatablesFilter.java:73)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
The line where I have arrowed is the line in the service that makes the call to the database. I have #Autowired DAO objects in the service, as below
#Service("UserService")
public class UserService implements UserServiceInterface{
#Autowired UsersDao userDao;
#Autowired PasswordServiceInterface passwordService;
#Override
public Users authenticate(String user,String password) {
boolean allowedIn = false;
List<Users> users = userDao.fetch(USERS.USERNAME, user);
//do something here
Other functions I use in similar services contain calls using the DSLContext object like
DSL.select(SOMETHING).from(SOMETABLE).fetch()
The DAO and DSLContext are stored as beans in PersistenceContext like so.
I am autowiring as a DSLContext and not a *Default*DSLContext as the jOOQ guide has a test method down the bottom showing only a DSLContext.
#Bean
public DefaultDSLContext dsl() {
return new DefaultDSLContext(configuration());
}
#Bean
public UsersDao userDao() { //bad because UsersDao isn't an interface???
return new UsersDao(configuration());
}
And this is the controller
#Controller
public class LoginController {
#Autowired UserServiceInterface userService;
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String login() {
return "login";
}
#RequestMapping(value = "/login/doLogin", method = RequestMethod.POST)
public String doLogin(#RequestParam("username")String username, #RequestParam("password") String password, HttpSession session) {
Users u = userService.authenticate(username, password);
if(u == null)
return "redirect:/error";
else {
session.setAttribute("user", u.getUserid());
session.setAttribute("role", u.getRoleid());
session.setAttribute("retailgroup", u.getGroupid());
return "redirect:/dashboard";
}
}
UserService is not the only service I get errors in -- all of my services are similar in that they contain one/both a DAO and a DSLContext Autowired object, with the same DAO configuration constructor as usersDao(), for example productsDao(). The Products service has this DAO and a DSLContext object, and much the same as the UsersService it makes calls to the database.
Sometimes I'll get this connection issue logging in, other times it will be fine and I can browse the site and look at products for a little while, but then randomly I'll get a 'connection is closed!' error coming from another service (there are about 5 that are written in the same way).
So my questions are
Where do I use the #Transactional annotation, and what does it actually do. Does my omission of the #Transactional annotation mean I am causing myself problems? I have previously added it in at all locations that use the DB, but I cant be sure if it was actually helping as I was still getting the same errors.
Is it an issue with my scope for something? I know beans are default as singleton - I've written my controllers in such a way that they use session stored attributes to pass to the services (which are all left as default singletons), so that they may only select data that a certain user is allowed to see.
Since the connectionPool is closing a connection twice, does this mean that the issue is that thread A and thread B go for a connection at the same time, do something with it, and then both close? Why is this happening using the configuration from the above guide? How do I ensure thread safety or is that not the problem?
Are the DAO beans supposed to be interfaces, as from my brief history with Spring I am led to believe a lot(many/all?) #Autowired beans should be? Am I supposed to be using the interface org.jooq.DAOImpl which is the interface that all the jOOQ generated DAOs seem to implement?
#Bean
public org.jooq.impl.DAOImpl usersDao() {
return new usersDao(configuration());
}
Apologies for the long question, any help would be greatly appreciated. Thanks.
Edit: This is my configuration in PersistenceContext class
#Configuration
#PropertySource("classpath:config.properties")
public class PersistenceContext {
#Autowired
private Environment env;
#Bean(destroyMethod = "close")
public DataSource dataSource() {
BoneCPDataSource dataSource = new BoneCPDataSource();
dataSource.setDriverClass(env.getRequiredProperty("db.driver"));
dataSource.setJdbcUrl(env.getRequiredProperty("db.url"));
dataSource.setUsername(env.getRequiredProperty("db.username"));
dataSource.setPassword(env.getRequiredProperty("db.password"));
dataSource.setMaxConnectionsPerPartition(20);
dataSource.setPartitionCount(2);
dataSource.setCloseConnectionWatch(true);
return dataSource;
}
#Bean
public LazyConnectionDataSourceProxy lazyConnectionDataSource() {
return new LazyConnectionDataSourceProxy(dataSource());
}
#Bean
public TransactionAwareDataSourceProxy transactionAwareDataSource() {
return new TransactionAwareDataSourceProxy(lazyConnectionDataSource());
}
#Bean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(lazyConnectionDataSource());
}
#Bean
public DataSourceConnectionProvider connectionProvider() {
return new DataSourceConnectionProvider(transactionAwareDataSource());
}
#Bean
public JOOQToSpringExceptionTransformer jooqToSpringExceptionTransformer() {
return new JOOQToSpringExceptionTransformer();
}
#Bean
public DefaultConfiguration configuration() {
DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
jooqConfiguration.set(connectionProvider());
jooqConfiguration.set(new DefaultExecuteListenerProvider(
jooqToSpringExceptionTransformer()
));
String sqlDialectName = env.getRequiredProperty("jooq.sql.dialect");
SQLDialect dialect = SQLDialect.valueOf(sqlDialectName);
jooqConfiguration.set(dialect);
return jooqConfiguration;
}
#Bean
public DefaultDSLContext dsl() {
return new DefaultDSLContext(configuration());
}
#Bean
public UsersDao userDao() {
return new UsersDao(configuration());
}
}
After re-reading your question and your chat, I can tell that it is really most likely due to your using version 3.2.0, which had this rather severe bug here:
https://github.com/jOOQ/jOOQ/issues/2863
That bug was fixed in 3.2.2, to which (or later) you should upgrade.

Spring binding exception when a form is submitted

Stuck and have no clue why Spring Form is not able to submit successfully [gives binding issue] when pre-populated in get Request call loadForm, but works fine when populated in a method setupFormObject with #ModelAttribute annotation tag. I can provide a simple example in github to test out if asked for :)
Example below
#ModelAttribute("showForm")
public ShowForm setupFormObject() {
//Instantiate showForm with data
return showForm;
}
#RequestMapping(method = RequestMethod.GET)
public ModelAndView loadForm(#RequestParam("id") String id, HttpSession session) {
ModelAndView modelAndView = new ModelAndView(nextPage);
//Instantiate showForm with data
//modelAndView.addObject("showForm", showForm);
return modelAndView;
}
#RequestMapping(method = RequestMethod.POST)
public String post(#ModelAttribute("showForm") ShowForm showForm, BindingResult result, final RedirectAttributes redirectAttrs) {
//I see changed data here in showForm when populated using #setupFormObject
//See an exception in JSP with binding error if populated in loadForm
return "";
}
Stack Trace as requested. This exception is from github example.
`HTTP Status 500 - Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'users[0]' of bean class [com.example.UserForm]: Illegal attempt to get property 'users' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'users' of bean class [com.example.UserForm]: Could not instantiate property type [com.example.UserEntity] to auto-grow nested property path: java.lang.InstantiationException: com.example.UserEntity`
`type Exception report`
`message Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'users[0]' of bean class [com.example.UserForm]: Illegal attempt to get property 'users' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'users' of bean class [com.example.UserForm]: Could not instantiate property type [com.example.UserEntity] to auto-grow nested property path: java.lang.InstantiationException: com.example.UserEntity`
`description The server encountered an internal error that prevented it from fulfilling this request.`
`exception`
`org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'users[0]' of bean class [com.example.UserForm]: Illegal attempt to get property 'users' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'users' of bean class [com.example.UserForm]: Could not instantiate property type [com.example.UserEntity] to auto-grow nested property path: java.lang.InstantiationException: com.example.UserEntity`
`org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:927)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:822)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)`
`root cause`
`org.springframework.beans.InvalidPropertyException: Invalid property 'users[0]' of bean class [com.example.UserForm]: Illegal attempt to get property 'users' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'users' of bean class [com.example.UserForm]: Could not instantiate property type [com.example.UserEntity] to auto-grow nested property path: java.lang.InstantiationException: com.example.UserEntity
org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:829)
org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:556)
org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:533)
org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:894)
org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:699)
org.springframework.validation.DataBinder.doBind(DataBinder.java:595)
org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:191)
org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:112)
org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.bindRequestParameters(ServletModelAttributeMethodProcessor.java:153)
org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:106)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:123)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:746)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:822)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
`
Your help is highly appreciated
Thanks
The issue is actually that UserEntity does not have a default constructor, if you add the constructor it will work cleanly:
public UserEntity(){
//
}
I think what's happening is that the way your form is declared in the JSP, when submitting it it will assume that there is a UserEntity instance at position 0 in the users List of the UserForm instance, but it actually stumbles over a null reference.
Yes, you do add some UserEntity instances to the model when the form is displayed (using the loadForm method which is mapped to HTTP Get), but when you submit the form, a new model object is created, and this one will only have nulls in the users List.
Try making the model session scoped, this way the model instance you create when the form is shown will be reused when the form is submitted. Or create your own implementation of List that will return a new instance of UserEntity when a get(int position) is performed and there's nothing there.

How to handle Error/Exception on multiple database connections with spring and hibernate?

I am using spring and hibernate to work on multiple database server save,update simultaneously using 2 datasource configuration.
I am using
org.springframework.jdbc.datasource.DriverManagerDataSource
class for creating datasource.
If both the database server up/running then it's work fine.
If I close one of my database server and trying to catch the exception then it's not coming in catch block
and the stack trace error displaying on my web browser.
Stack Trace:
** BEGIN NESTED EXCEPTION **
java.net.ConnectException
MESSAGE: Connection refused: connect
STACKTRACE:
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:525)
at java.net.Socket.connect(Socket.java:475)
at java.net.Socket.(Socket.java:372)
at java.net.Socket.(Socket.java:215)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:256)
at com.mysql.jdbc.MysqlIO.(MysqlIO.java:271)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2771)
at com.mysql.jdbc.Connection.(Connection.java:1555)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at java.sql.DriverManager.getConnection(DriverManager.java:582)
at java.sql.DriverManager.getConnection(DriverManager.java:154)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:173)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:164)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:149)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:119)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:82)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:116)
at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:54)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2186)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2666)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:562)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:550)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:546)
at org.springframework.orm.hibernate3.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:686)
at org.springframework.orm.hibernate3.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:1)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:683)
at com.service.RegistrationServiceImpl.add(RegistrationServiceImpl.java:56)
at com.controller.RegistrationController.onSubmit(RegistrationController.java:48)
at org.springframework.web.servlet.mvc.SimpleFormController.processFormSubmission(SimpleFormController.java:272)
at org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:268)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:763)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:709)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:613)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:536)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:879)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Thread.java:619)
** END NESTED EXCEPTION *
How can I handle this exception.
I want to display in my GUI that one of my db server is down If any of my db server is down.
Please help on this.
I think there are two options:
List item You should catch the exception in your service layer (like for example in RegistrationServiceImpl), but you will have to do this in all your service classes.
Create a Servlet filter that catches this specific exception and redirect the user to a page showing something like "Sorry, the database is down".
There is #ExceptionHandler annotation in spring. You can create a handler method in some common class of yours. Whenever an exception is thrown you can conveniently show the message you want depending on the exception thrown something like this
#Component
public class BaseController {
#ExceptionHandler(Throwable.class)
public ModelAndView handleException(Throwable throwable, HttpServletRequest request){
ModelAndView view = null;
if (throwable instanceof ConnectException){
view = //set message and return view;
}else if (throwable instanceof someOtherException) {
//do something else;
//handle as many exceptions as you want
}else {
//do something by default for other unhandled/generic exceptions
}
return view;
}
}
The documentation explains more on the return types supported.
You can also make the handler to handle only the kind of exception you want, something like this:
#ExceptionHandler(ConnectException.class)
public ModelAndView handleException(ConnectException ex, HttpServletRequest request){
// handle it
}
You can check this example which is on similar lines.
I hope this helps. Cheers :)

Resources