How to insert data in db with the methode afterJob - spring

In my application I have to insert somme data in db, this data contian the ExitStatut of the Job,
my code is
#Override
public void afterJob(JobExecution jobExecution) {
if (jobExecutionContext.get(ConstantesApps.TRACE) != null) {
Trace trace = (Trace)jobExecutionContext.get(ConstantesApps.TRACE);
trace.setHeureFinTraitement(jobExecution.getEndTime());
trace.setCodeRetour(getCodeRetour(jobExecution));
traceRepository.update(trace);
}
}
i have this exception :
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:993) ~[hibernate-entitymanager-4.2.0.Final.jar:4.2.0.Final]
at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_31]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_31]
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:342) ~[spring-orm-4.0.5.RELEASE.jar:4.0.5.RELEASE]
at com.sun.proxy.$Proxy29.flush(Unknown Source) ~[na:na]
at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source) ~[na:na]

well the below piece of code which I wrote , worked for me --
In you Main class - load your application context in a static variable - APP_CONTEXT
If you are not using XML based approach - then get the dataSource by auto-wiring it and then you can use below code -
Connection conn = null;
PreparedStatement pstmt= null;
try {
DataSource dataSource = (DataSource) Main.APP_CONTEXT
.getBean("dataSource");
conn = dataSource.getConnection();
pstmt = conn.prepareStatement(" your SQL query to insert ");
pstmtMstr.executeQuery();
} catch (Exception e) {
}finally{
if(pstmt!=null){
pstmt.close();
}if(conn!=null){
conn.close();
}
}

The exception message is very clear - you are invoking this code outside of transaction boundaries. You had committed or rolled back your transaction before this code executed or afterJob is executed in a separate thread.
In both cases you need to define transactional context in which afterJob is executed.

You are directly calling traceRepository.update(trace); which could be a Spring #Repository bean but not annotated with #Transactional.
Instead you can call some Service method that is annotated with #Transactional. From that Service method you can invoke traceRepository.update(trace); which will run in transactional context.

Related

Saving a record using JPA in a Spring Boot Scheduler

I'm using a Spring Boot Scheduler to run a query on the DB daily to find some records based on a condition and update the records returned. Fetching the records using JPA works fine, but when I loop through them, update them, and try to save each updated record I get the following error:
Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
Caused by: javax.persistence.RollbackException: Error while committing the transaction at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81) at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104) at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562) ... 30 more Caused by: java.lang.NullPointerException at com.xxx.yyy.config.JpaAuditingConfiguration.auditorProvider$lambda-0(JpaAuditingConfiguration.kt:15) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) at com.sun.proxy.$Proxy168.getCurrentAuditor(Unknown Source) at java.base/java.util.Optional.map(Optional.java:265) at org.springframework.data.auditing.AuditingHandler.getAuditor(AuditingHandler.java:109) at org.springframework.data.auditing.AuditingHandler.markModified(AuditingHandler.java:104) at org.springframework.data.jpa.domain.support.AuditingEntityListener.touchForUpdate(AuditingEntityListener.java:112).
Here is the scheduler code I have. If I run the same code inside my service and call it using an endpoint everything works fine:
#Component
class Scheduler(
private val repository: Repository
) {
#Scheduled(cron = "0 0 2 * * *")
fun expire() {
val records = repository.findRecords()
for (record in records) {
try {
// Call some external API using record.id but this part is commented out for now until the saving works
record.active = false
repository.save(record)
} catch (ex: Exception) {
logger.error("Error expiring record " + record.id)
logger.error("Exception: ${ex.printStackTrace()}")
continue
}
}
}
}
the null pointer exception happens in the JpaAuditingConfiguration config I use for storing the created_at and last_modified_at dates. Here is the code I have for that class:
#Configuration
#EnableJpaAuditing(auditorAwareRef = "auditorProvider")
class JpaAuditingConfiguration {
#Bean
fun auditorProvider(): AuditorAware<String> {
return AuditorAware { Optional.of(SecurityContextHolder.getContext().authentication.name) }
}
}
Your JpaAuditingConfiguration requires the security context to be non null when you make modifications. When you're running your task in a scheduler there is no active request, so no active session, and therefore your authentication is null.
Usually, this is solved by making a special app user and manually authenticating them in your scheduled task.

Connection closed when saving blob

I'm having a problem when uploading files on a weblogic application.
Once the fileuploader has finished saving the file, the following exception appears:
java.sql.SQLException: Conexión cerrada
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:263)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:271)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:445)
at oracle.sql.BLOB.getDBAccess(BLOB.java:882)
at oracle.sql.BLOB.freeTemporary(BLOB.java:584)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.jdbc.support.lob.OracleLobHandler$OracleLobCreator.close(OracleLobHandler.java:412)
at org.springframework.jdbc.support.lob.SpringLobCreatorSynchronization.afterCompletion(SpringLobCreatorSynchronization.java:76)
at org.springframework.transaction.support.TransactionSynchronizationUtils.invokeAfterCompletion(TransactionSynchronizationUtils.java:133)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.invokeAfterCompletion(AbstractPlatformTransactionManager.java:951)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCompletion(AbstractPlatformTransactionManager.java:926)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:319)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy74.guardarFichero(Unknown Source)
At other environments this problem doesn't appear, so I think it must be some configuration on the JDBC driver but I'm not sure wich one I have to modify.
The invoking struts
private void adjuntarFichero()throws Exception {
logger.debug("uploadFileName = "+uploadFileName);
if (uploadFileName!=null && !uploadFileName.equals("")) {
HttpSession session = request.getSession();
HashMap<Long,String> ficheros = (HashMap<Long,String>)session.getAttribute("ficheros");
if (ficheros == null) ficheros = new HashMap<Long,String>();
Fichero file = new FicheroImpl();
file.setNombre(uploadFileName);
file.setFichero(getBytesFromFile(upload));
file = gestorFichero.guardarFichero(file);
ficheros.put(file.getId(), uploadFileName);
session.setAttribute("ficheros", ficheros);
}
}
the error is produced inside the "guardarFichero" method, who invokes a DAO class that takes care of the saving
public abstract class gestorFichero
extends org.springframework.orm.hibernate3.support.HibernateDaoSupport{
public Fichero guardarFichero (Fichero fichero){
Debug.prec(fichero, "El fichero no puede ser nulo");
return (Fichero)create(TRANSFORM_NONE, fichero);
}
public java.lang.Object create(final int transform, final com.aena.sgc.Fichero fichero)
{
if (fichero == null){
throw new IllegalArgumentException("Fichero.create - 'fichero' can not be null");
}
this.getHibernateTemplate().save(fichero);
return this.transformEntity(transform, fichero);
}
Finally I discovered wich was the problem.
It was related to the driver class. Originally we had the datasource configured to use the XA driver oracle.jdbc.xa.client.OracleXADataSource and whenever we finished uploading a file, the exception was thrown.
Once I changed the driver to oracle.jdbc.OracleDriver these errors dissapeared.

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.

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 :)

jpa transaction stop rollback

I have the following code. I want the execution to continue even if there is an exception
#Transactional(noRollbackFor={PersistenceException.class, PSQLException.class,SQLGrammarException.class})
public void executeQuery(String parameterName){
Query query = objectManager.getEntityManager().createNativeQuery("SOME UPDATE QUERY");
Map<String, String> paramMap = (Map) destTableMap.get(parameterName);
query.setParameter("xyz",5);
try{
query.executeUpdate();
}catch(Exception ex){
ex.printStackTrace();
}
}
The exception stack trace that I receive is
Exception in thread "main" org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:476)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
at
Caused by: javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
... 11 more
From the documentation:
If the Session throws an exception, including any SQLException,
immediately rollback the database transaction, call Session.close()
and discard the Session instance. Certain methods of Session will not
leave the session in a consistent state. No exception thrown by
Hibernate can be treated as recoverable. Ensure that the Session will
be closed by calling close() in a finally block.
The transaction must be rolled back. So, if you want to continue executing if Hibernate throws an exception, you should put the execute the executeQuery method in its own transaction, using the REQUIRES_NEW propagation in the #Transactional annotation. This way, only this short transaction will be rolled back.
I tried to use the following to avoid this TransactionSystemException: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
#Transactional(readOnly = false, rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public String foo(Object obj, String tableName, BindingResult result) throws Exception
{
// put some code here
}

Resources