package com.snaphop.jooq;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import org.jooq.ExecuteContext;
import org.jooq.impl.DefaultExecuteListener;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLExceptionTranslator;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
/**
* Example provided by Adam Gent
*/
public class SpringExceptionTranslationExecuteListener
extends DefaultExecuteListener {
@Override
public void start(ExecuteContext ctx) {
DataSource dataSource = ctx.getDataSource();
Connection c = DataSourceUtils.getConnection(dataSource);
ctx.setConnection(c);
}
@Override
public void exception(ExecuteContext ctx) {
SQLException ex = ctx.sqlException();
Statement stmt = ctx.statement();
Connection con = ctx.getConnection();
DataSource dataSource = ctx.getDataSource();
// This note and code below comes from
// JdbcTemplate.execute(StatementCallback)
// Release Connection early, to avoid potential connection pool
// deadlock in the case when the exception translator hasn't
// been initialized yet.
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, dataSource);
con = null;
ctx.exception(getExceptionTranslator(dataSource)
.translate("jOOQ", ctx.sql(), ex));
}
/**
* Return the exception translator for this instance.
*
Creates a default {@link SQLErrorCodeSQLExceptionTranslator}
* for the specified DataSource if none set, or a
* {@link SQLStateSQLExceptionTranslator} in case of no DataSource.
* @see #getDataSource()
*/
public synchronized SQLExceptionTranslator
getExceptionTranslator(DataSource dataSource) {
// This method probably does not need to be synchronized but in
// Spring it was because of a mutable field on the JdbcTemplate.
// Also I have no idea how expensive it is to create a translator
// as one will get created on every exception.
final SQLExceptionTranslator exceptionTranslator;
if (dataSource != null) {
exceptionTranslator =
new SQLErrorCodeSQLExceptionTranslator(dataSource);
}
else {
exceptionTranslator = new SQLStateSQLExceptionTranslator();
}
return exceptionTranslator;
}
}
A nice way of using jOOQ with Spring
This blog post is outdated. For a more up-to-date example of how to integrate jOOQ with Spring, please consider the relevant sections of the jOOQ manual!
A nice way of using jOOQ with Spring was recently discussed on Stack Overflow by Adam Gent:
http://adamgent.com/post/31128631472/getting-jooq-to-work-with-spring-correctly
The essence of it was given here in this gist:
See the relevant Stack Overflow answer for more details:
https://stackoverflow.com/a/12326885/521799
you might also want to check my anwer I added to this post since it seems to be a lot easier: https://stackoverflow.com/a/14243136/1964204
Awesome, Peter, thanks! I think this aligns well with what Sergey Epik once mentioned on the jOOQ user group:
https://groups.google.com/d/msg/jooq-user/TYUg6XjPYlk/VfxS5TFokBgJ
Except that your solution is a programmatic one, not a configurative one. Besides, it seems more concise than Sergey’s solution…