{"id":20557,"date":"2014-01-28T01:00:46","date_gmt":"2014-01-27T23:00:46","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=20557"},"modified":"2014-01-27T20:37:25","modified_gmt":"2014-01-27T18:37:25","slug":"using-jooq-with-spring-configuration","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html","title":{"rendered":"Using jOOQ with Spring: Configuration"},"content":{"rendered":"<p>I have had my share of performance problems caused by ORMs. Although I have to admit that most of these problems were really caused by yours truly, I have started to think that using ORMs in read-only operations is not worth it.<\/p>\n<p>I started to look for alternative ways to implement these operations.<\/p>\n<p>That is how I ran into <a href=\"http:\/\/www.jooq.org\/\" target=\"_blank\">jOOQ<\/a> which states that:<\/p>\n<blockquote>\n<p>jOOQ generates Java code from your database and lets you build typesafe SQL queries through its fluent API.<\/p>\n<\/blockquote>\n<p>This looks very interesting and I decided to give jOOQ a shot and share my findings with you.<\/p>\n<p>This blog post is the first part of my Using jOOQ with Spring series and it describes how we can get the required dependencies and configure the application context of our application.<\/p>\n<p>Let\u2019s get started.<\/p>\n<h2>Getting the Required Dependencies with Maven<\/h2>\n<p>The dependencies of our application are:<\/p>\n<ul>\n<li><a href=\"http:\/\/projects.spring.io\/spring-framework\/\" target=\"_blank\">Spring Framework<\/a> 3.2.6. At this point our example uses the <em>aop<\/em>, <em>beans<\/em>, <em>core<\/em>, <em>context<\/em>, <em>context-support<\/em>, <em>jdbc<\/em>, and <em>tx<\/em> modules.<\/li>\n<li><a href=\"http:\/\/cglib.sourceforge.net\/\" target=\"_blank\">cglib<\/a> 3.1.<\/li>\n<li><a href=\"http:\/\/jolbox.com\/\" target=\"_blank\">BoneCP<\/a> 0.8.0. We use BoneCP as the connection pool of our example application.<\/li>\n<li><a href=\"http:\/\/www.jooq.org\/\" target=\"_blank\">jOOQ<\/a> 3.2.2.<\/li>\n<li><a href=\"http:\/\/www.h2database.com\/html\/main.html\" target=\"_blank\">H2<\/a> 1.3.174. We use H2 as the database of our example application.<\/li>\n<\/ul>\n<p>If you want to get more information about the modules of Spring Framework, read <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.6.RELEASE\/spring-framework-reference\/htmlsingle\/#overview-modules\" target=\"_blank\">section 1.2 of the Spring Framework Reference Documentation<\/a>.<\/p>\n<p>The reason why this example application uses Spring Framework 3.2.6 instead of 4.0 is that at the moment <a href=\"https:\/\/github.com\/springtestdbunit\/spring-test-dbunit\/issues\/46\" target=\"_blank\">spring-test-dbunit isn\u2019t compatible with Spring Framework 4.0<\/a>.<\/p>\n<p>The relevant part of the <em>pom.xml<\/em> file looks as follows:<\/p>\n<pre class=\"brush:xml\">&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-aop&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.6.RELEASE&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-beans&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.6.RELEASE&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-core&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.6.RELEASE&lt;\/version&gt;\r\n&lt;\/Dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-context&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.6.RELEASE&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-context-support&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.6.RELEASE&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-expression&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.6.RELEASE&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-jdbc&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.6.RELEASE&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-tx&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.6.RELEASE&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n       \r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;cglib&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;cglib&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.1&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;com.jolbox&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;bonecp&lt;\/artifactId&gt;\r\n    &lt;version&gt;0.8.0.RELEASE&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.jooq&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;jooq&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.2&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;com.h2database&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;h2&lt;\/artifactId&gt;\r\n    &lt;version&gt;1.3.174&lt;\/version&gt;\r\n&lt;\/dependency&gt;<\/pre>\n<ul>\n<li>The example application of this blog post has other dependencies as well. You can see the full dependency list by taking a look at the <a href=\"https:\/\/github.com\/pkainulainen\/jooq-with-spring-examples\/blob\/master\/configuration\/pom.xml\" target=\"_blank\">pom.xml file<\/a>.<\/li>\n<\/ul>\n<p>Let\u2019s move on find out how we can transform the exceptions thrown by jOOQ to Spring <em>DataAccessExceptions<\/em>.<\/p>\n<h2>Transforming jOOQ Exceptions to Spring DataAccessExceptions<\/h2>\n<p>Why should we transform the exceptions thrown by jOOQ to Spring <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/dao\/DataAccessException.html\" target=\"_blank\"><em>DataAccessExceptions<\/em><\/a>?<\/p>\n<p>One reason to do so is that we want that our integration works in the same way than <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/spring-framework-reference\/htmlsingle\/#dao\" target=\"_blank\">the DAO support of Spring Framework<\/a>. One essential part of this support is a <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/spring-framework-reference\/htmlsingle\/#dao-exceptions\" target=\"_blank\">consistent exception hierarchy<\/a>:<\/p>\n<blockquote>\n<p>Spring provides a convenient translation from technology-specific exceptions like <em>SQLException<\/em> to its own exception class hierarchy with the <em>DataAccessException<\/em> as the root exception. These exceptions wrap the original exception so there is never any risk that one might lose any information as to what might have gone wrong.<\/p>\n<\/blockquote>\n<p>In other words, if we want that our application is \u201ca good citizen\u201d, it makes sense to ensure that our configuration transforms the exceptions thrown by jOOQ to Spring <em>DataAccessExceptions<\/em>.<\/p>\n<p>We can create a component which provides this functionality by following these steps:<\/p>\n<ol>\n<li>Create a <em>JOOQToSpringExceptionTransformer<\/em> class which extends the <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/impl\/DefaultExecuteListener.html\" target=\"_blank\"><em>DefaultExecuteListener<\/em><\/a> class. The <em>DefaultExecuteListener<\/em> class is the public default implementation of the <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/ExecuteListener.html\" target=\"_blank\"><em>ExecuteListener<\/em><\/a> interface which provides listener methods for different life cycle events of a single query execution.<\/li>\n<li>Override <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/impl\/DefaultExecuteListener.html#exception%28org.jooq.ExecuteContext%29\" target=\"_blank\">the <em>exception(ExecuteContext ctx)<\/em> method of the <em>DefaultExecuteListener<\/em> class<\/a>. This method is called if an exception is thrown at any moment of the execution life cycle. Implement the method by following these steps:\n<ol>\n<li>Get a <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/SQLDialect.html\" target=\"_blank\"><em>SQLDialect<\/em><\/a> object from the <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/ExecuteContext.html#configuration%28%29\" target=\"_blank\">jOOQ configuration<\/a>.<\/li>\n<li>Create an object which implements the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/support\/SQLExceptionTranslator.html\" target=\"_blank\"><em>SQLExceptionTranslator<\/em><\/a> interface by following these rules:\n<ol>\n<li>If the configured SQL dialect is found, create a new <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/support\/SQLErrorCodeSQLExceptionTranslator.html\" target=\"_blank\"><em>SQLErrorCodeSQLExceptionTranslator<\/em><\/a> object and pass the name of the SQL dialect as a constructor argument. This class \u201cselects\u201d the right <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/dao\/DataAccessException.html\" target=\"_blank\"><em>DataAccessException<\/em><\/a> by analyzing vendor specific error codes.<\/li>\n<li>If the SQL dialect isn\u2019t found, create a new <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/support\/SQLStateSQLExceptionTranslator.html\" target=\"_blank\"><em>SQLStateSQLExceptionTranslator<\/em><\/a> object. This class \u201cselects\u201d the right <em>DataAccessException<\/em> by analyzing the SQL state stored to the <a href=\"http:\/\/docs.oracle.com\/javase\/6\/docs\/api\/java\/sql\/SQLException.html\" target=\"_blank\"><em>SQLException<\/em><\/a>.<\/li>\n<\/ol>\n<\/li>\n<li>Create the <em>DataAccessException<\/em> object by <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/support\/SQLExceptionTranslator.html#translate%28java.lang.String,%20java.lang.String,%20java.sql.SQLException%29\" target=\"_blank\">using the created SQLExceptionTranslator object<\/a>.<\/li>\n<li>Pass the thrown <em>DataAccessException<\/em> forward to the <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/ExecuteContext.html\" target=\"_blank\"><em>ExecuteContext<\/em><\/a> object given as a method argument.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>The source code of the <em>JOOQToSpringExceptionTransformer<\/em> class looks as follows:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush:java\">import org.jooq.ExecuteContext;\r\nimport org.jooq.SQLDialect;\r\nimport org.jooq.impl.DefaultExecuteListener;\r\nimport org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;\r\nimport org.springframework.jdbc.support.SQLExceptionTranslator;\r\nimport org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;\r\n\r\n\r\npublic class JOOQToSpringExceptionTransformer extends DefaultExecuteListener {\r\n\r\n    @Override\r\n    public void exception(ExecuteContext ctx) {\r\n        SQLDialect dialect = ctx.configuration().dialect();\r\n        SQLExceptionTranslator translator = (dialect != null)\r\n                ? new SQLErrorCodeSQLExceptionTranslator(dialect.name())\r\n                : new SQLStateSQLExceptionTranslator();\r\n\r\n        ctx.exception(translator.translate(\"jOOQ\", ctx.sql(), ctx.sqlException()));\r\n    }\r\n}<\/pre>\n<p><strong>This is not my idea<\/strong>. I got this idea from <a href=\"https:\/\/gist.github.com\/azell\/5655888\" target=\"_blank\">Adam Zell\u2019s Gist<\/a>.<\/p>\n<p><strong>Additional reading:<\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/www.jooq.org\/doc\/3.2\/manual-single-page\/#custom-execute-listeners\" target=\"_blank\">Section 4.2.5 \u201cCustom ExecuteListeners\u201d of the jOOQ User Manual<\/a><\/li>\n<li><a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/spring-framework-reference\/htmlsingle\/#jdbc-SQLExceptionTranslator\" target=\"_blank\">Section 14.2.3 \u201cSQLExceptionTranslator\u201d of the Spring Framework Reference Documentation<\/a><\/li>\n<\/ul>\n<p>Our job isn\u2019t done yet. Let\u2019s put all pieces together and finish our job by configuring the application context of our example application.<\/p>\n<h2>Configuring the Application Context<\/h2>\n<p>This section explains how we can configure the application context of our application by using Java configuration.<\/p>\n<p>Let\u2019s start by creating a properties file which contains the configuration of our example application.<\/p>\n<blockquote>\n<p>The build process of the actual application is based on Maven profiles. This ensures that we can use different configuration in different environments. You can get more information about this by reading my blog post titled <a href=\"\/programming\/tips-and-tricks\/creating-profile-specific-configuration-files-with-maven\/\">Creating Profile Specific Configuration Files with Maven<\/a><\/p>\n<\/blockquote>\n<h3>Creating the Properties File<\/h3>\n<p>We can create the properties file by following these steps:<\/p>\n<ol>\n<li>Configure the data base connection. We need to configure the JDBC driver class, JDBC url, username of the database user, and password of the database user.<\/li>\n<li>Configure the name of the used SQL dialect.<\/li>\n<li>Configure the name of the SQL script which creates the database of our example application (This is an optional step which isn\u2019t required if your application doesn\u2019t use an embedded database).<\/li>\n<\/ol>\n<p>The <em>application.properties<\/em> file looks as follows:<\/p>\n<pre class=\"brush:java\">#Database Configuration\r\ndb.driver=org.h2.Driver\r\ndb.url=jdbc:h2:target\/jooq-example\r\ndb.username=sa\r\ndb.password=\r\n\r\n#jOOQ Configuration\r\njooq.sql.dialect=H2\r\n\r\n#DB Schema\r\ndb.schema.script=schema.sql<\/pre>\n<ul>\n<li>The <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/SQLDialect.html\" target=\"_blank\">Javadoc of the <em>SQLDialect<\/em> Enum<\/a> specifies the list of database dialects supported by jOOQ.<\/li>\n<\/ul>\n<p>Let\u2019s move on and find out how we can configure the application context of our application by using Java configuration.<\/p>\n<h3>Creating the Configuration Class<\/h3>\n<p>We can configure the application context of our application by following these steps:<\/p>\n<ol>\n<li>Create a <em>PersistenceContext<\/em> class.<\/li>\n<li>Ensure that the created class is recognized as a configuration class by annotating the class with the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/context\/annotation\/Configuration.html\" target=\"_blank\"><em>@Configuration<\/em><\/a> annotation.<\/li>\n<li>Ensure that the jOOQ repositories of our application are found during the component scan. We can do this by annotating the configuration class with the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/context\/annotation\/ComponentScan.html\" target=\"_blank\"><em>@ComponentScan<\/em><\/a> annotation.<\/li>\n<li>Enable the annotation-driven transaction management by annotating the configuration class with the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/transaction\/annotation\/EnableTransactionManagement.html\" target=\"_blank\"><em>@EnableTransactionManagement<\/em><\/a> annotation.<\/li>\n<li>Ensure that the configuration of our application is loaded from the <em>application.properties<\/em> file which is found from the classpath. We can use do this by annotation the configuration class with the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/context\/annotation\/PropertySource.html\" target=\"_blank\"><em>@PropertySource<\/em><\/a> annotation.<\/li>\n<li>Add an <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/core\/env\/Environment.html\" target=\"_blank\"><em>Environment<\/em><\/a> field to the configuration class and annotate the field with the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/beans\/factory\/annotation\/Autowired.html\" target=\"_blank\"><em>@Autowired<\/em><\/a> annotation. We use the <em>Environment<\/em> object to get the property values of the configuration properties which are loaded from the <em>application.properties<\/em> file.<\/li>\n<li>Configure the <a href=\"http:\/\/docs.oracle.com\/javase\/6\/docs\/api\/javax\/sql\/DataSource.html\" target=\"_blank\"><em>DataSource<\/em><\/a> bean. Because our application uses BoneCP, we have create a <a href=\"http:\/\/jolbox.com\/bonecp\/downloads\/site\/apidocs\/com\/jolbox\/bonecp\/BoneCPDataSource.html\" target=\"_blank\"><em>BoneCPDataSource<\/em><\/a> object as our data source.<\/li>\n<li>Configure the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/datasource\/LazyConnectionDataSourceProxy.html\" target=\"_blank\"><em>LazyConnectionDataSourceProxy<\/em><\/a> bean. This bean ensures that the database connection are fetched lazily (i.e. when first statement is created).<\/li>\n<li>Configure the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/datasource\/TransactionAwareDataSourceProxy.html\" target=\"_blank\"><em>TransactionAwareDataSourceProxy<\/em><\/a> bean. This bean ensures that all JDBC connection are aware of Spring-managed transactions. In other words, JDBC connections participates in thread-bound transactions.<\/li>\n<li>Configure the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/datasource\/DataSourceTransactionManager.html\" target=\"_blank\"><em>DataSourceTransactionManager<\/em><\/a> bean. <strong>We must pass the <em>LazyConnectionDataSourceProxy<\/em> bean as as constructor argument when we create a new <em>DataSourceTransactionManager<\/em> object<\/strong>.<\/li>\n<li>Configure the <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/impl\/DataSourceConnectionProvider.html\" target=\"_blank\"><em>DataSourceConnectionProvider<\/em><\/a> bean. jOOQ will get the used connections from the <em>DataSource<\/em> given as a constructor argument. <strong>We must pass the <em>TransactionAwareDataSourceProxy<\/em> bean as a constructor argument when we create a new <em>DataSourceConnectionProvider<\/em> object<\/strong>. This ensures that the queries created jOOQ participate in Spring-managed transactions.<\/li>\n<li>Configure the <em>JOOQToSpringExceptionTransformer<\/em> bean.<\/li>\n<li>Configure the <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/impl\/DefaultConfiguration.html\" target=\"_blank\"><em>DefaultConfiguration<\/em><\/a> bean. This class is the default implementation of the <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/Configuration.html\" target=\"_blank\"><em>Configuration<\/em><\/a> interface, and we can use it to configure jOOQ. We have to configure three things:\n<ol>\n<li>We have to set the <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/ConnectionProvider.html\" target=\"_blank\"><em>ConnectionProvider<\/em><\/a> which is used to obtain and release database connections.<\/li>\n<li>We have to configure the <a href=\"http:\/\/www.jooq.org\/doc\/3.2\/manual-single-page\/#custom-execute-listeners\" target=\"_blank\">custom execute listeners<\/a>. In other words, we have to add <em>JOOQToSpringExceptionTransformer<\/em> bean to the created <em>DefaultConfiguration<\/em> object. This ensures that the exceptions thrown by jOOQ are transformed to Spring <em>DataAccessExceptions<\/em>.<\/li>\n<li>We have to configure the used SQL dialect.<\/li>\n<\/ol>\n<\/li>\n<li>Configure the <a href=\"http:\/\/www.jooq.org\/javadoc\/latest\/org\/jooq\/impl\/DefaultDSLContext.html\" target=\"_blank\"><em>DefaultDSLContext<\/em><\/a> bean. We use this bean when we are creating database queries with jOOQ.<\/li>\n<li>Configure the <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/datasource\/init\/DataSourceInitializer.html\" target=\"_blank\"><em>DataSourceInitializer<\/em><\/a> bean. We use this bean to create the database schema of H2 database when our application is started (If you don\u2019t use an embedded database, you don\u2019t have to configure this bean).<\/li>\n<\/ol>\n<p>The source code of the <em>PersistenceContext<\/em> class looks as follows:<\/p>\n<pre class=\"brush:java\">import com.jolbox.bonecp.BoneCPDataSource;\r\nimport org.jooq.SQLDialect;\r\nimport org.jooq.impl.DataSourceConnectionProvider;\r\nimport org.jooq.impl.DefaultConfiguration;\r\nimport org.jooq.impl.DefaultDSLContext;\r\nimport org.jooq.impl.DefaultExecuteListenerProvider;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.context.annotation.Bean;\r\nimport org.springframework.context.annotation.ComponentScan;\r\nimport org.springframework.context.annotation.Configuration;\r\nimport org.springframework.context.annotation.PropertySource;\r\nimport org.springframework.core.env.Environment;\r\nimport org.springframework.core.io.ClassPathResource;\r\nimport org.springframework.jdbc.datasource.DataSourceTransactionManager;\r\nimport org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;\r\nimport org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;\r\nimport org.springframework.jdbc.datasource.init.DataSourceInitializer;\r\nimport org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;\r\nimport org.springframework.transaction.annotation.EnableTransactionManagement;\r\n\r\nimport javax.sql.DataSource;\r\n\r\n@Configuration\r\n@ComponentScan({\"net.petrikainulainen.spring.jooq.todo\"})\r\n@EnableTransactionManagement\r\n@PropertySource(\"classpath:application.properties\")\r\npublic class PersistenceContext {\r\n\r\n    @Autowired\r\n    private Environment env;\r\n\r\n    @Bean(destroyMethod = \"close\")\r\n    public DataSource dataSource() {\r\n        BoneCPDataSource dataSource = new BoneCPDataSource();\r\n\r\n        dataSource.setDriverClass(env.getRequiredProperty(\"db.driver\"));\r\n        dataSource.setJdbcUrl(env.getRequiredProperty(\"db.url\"));\r\n        dataSource.setUsername(env.getRequiredProperty(\"db.username\"));\r\n        dataSource.setPassword(env.getRequiredProperty(\"db.password\"));\r\n\r\n        return dataSource;\r\n    }\r\n\r\n    @Bean\r\n    public LazyConnectionDataSourceProxy lazyConnectionDataSource() {\r\n        return new LazyConnectionDataSourceProxy(dataSource());\r\n    }\r\n\r\n    @Bean\r\n    public TransactionAwareDataSourceProxy transactionAwareDataSource() {\r\n        return new TransactionAwareDataSourceProxy(lazyConnectionDataSource());\r\n    }\r\n\r\n    @Bean\r\n    public DataSourceTransactionManager transactionManager() {\r\n        return new DataSourceTransactionManager(lazyConnectionDataSource());\r\n    }\r\n\r\n    @Bean\r\n    public DataSourceConnectionProvider connectionProvider() {\r\n        return new DataSourceConnectionProvider(transactionAwareDataSource());\r\n    }\r\n\r\n    @Bean\r\n    public JOOQToSpringExceptionTransformer jooqToSpringExceptionTransformer() {\r\n        return new JOOQToSpringExceptionTransformer();\r\n    }\r\n\r\n    @Bean\r\n    public DefaultConfiguration configuration() {\r\n        DefaultConfiguration jooqConfiguration = new DefaultConfiguration();\r\n\r\n        jooqConfiguration.set(connectionProvider());\r\n        jooqConfiguration.set(new DefaultExecuteListenerProvider(\r\n            jooqToSpringExceptionTransformer()\r\n        ));\r\n\r\n        String sqlDialectName = env.getRequiredProperty(\"jooq.sql.dialect\");\r\n        SQLDialect dialect = SQLDialect.valueOf(sqlDialectName);\r\n        jooqConfiguration.set(dialect);\r\n\r\n        return jooqConfiguration;\r\n    }\r\n\r\n    @Bean\r\n    public DefaultDSLContext dsl() {\r\n        return new DefaultDSLContext(configuration());\r\n    }\r\n\r\n    @Bean\r\n    public DataSourceInitializer dataSourceInitializer() {\r\n        DataSourceInitializer initializer = new DataSourceInitializer();\r\n        initializer.setDataSource(dataSource());\r\n\r\n        ResourceDatabasePopulator populator = new ResourceDatabasePopulator();\r\n        populator.addScript(\r\n                new ClassPathResource(env.getRequiredProperty(\"db.schema.script\"))\r\n        );\r\n\r\n        initializer.setDatabasePopulator(populator);\r\n        return initializer;\r\n    }\r\n}<\/pre>\n<p>If you want to configure the application context by using XML configurations files, the example application has a working <a href=\"https:\/\/github.com\/pkainulainen\/jooq-with-spring-examples\/blob\/master\/configuration\/src\/main\/resources\/exampleApplicationContext-persistence.xml\" target=\"_blank\">XML configuration file<\/a> as well.<\/p>\n<p><strong>Credits:<\/strong><\/p>\n<ul>\n<li>This configuration is based on <a href=\"http:\/\/www.jooq.org\/doc\/3.2\/manual-single-page\/#jooq-with-spring\" target=\"_blank\">section 3.4.3 of the jOOQ user manual<\/a>.<\/li>\n<li><a href=\"https:\/\/groups.google.com\/forum\/?fromgroups#!topic\/jooq-user\/XTDG9VVP-3I\" target=\"_blank\">The message posted by Sergey Epik<\/a> helped me to figure out how I can add custom ExecuteListeners to the jOOQ configuration.<\/li>\n<li><a href=\"http:\/\/stackoverflow.com\/a\/14243136\/313554\" target=\"_blank\">Peter Ertl<\/a> gave me an idea to use <em>LazyConnectionDataSourceProxy<\/em>.<\/li>\n<\/ul>\n<p>How do we know that this configuration works? That is a good question. We will talk about that in the following section.<\/p>\n<h2>Does This Really Work?<\/h2>\n<p>When I started to investigate how I can ensure that the database queries created with jOOQ participate in Spring-managed transactions, I noticed that <a href=\"https:\/\/github.com\/jOOQ\/jOOQ\/issues\/1836\" target=\"_blank\">it isn\u2019t an easy problem to solve<\/a>.<\/p>\n<p>The example application of this blog post has a few integration tests which ensure that transactions (commit and rollback) are working in a very simple scenario. However, there are two things which we must take into account when using the solution described in this blog post:<\/p>\n<p><strong>1. All database queries created with jOOQ must be executed inside a transaction.<\/strong><\/p>\n<p>The <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/datasource\/TransactionAwareDataSourceProxy.html\" target=\"_blank\">Javadoc of the <em>TransactionAwareDataSourceProxy<\/em> class<\/a> states:<\/p>\n<blockquote>\n<p>Delegates to <em>DataSourceUtils<\/em> for automatically participating in thread-bound transactions, for example managed by <em>DataSourceTransactionManager<\/em>. <em>getConnection<\/em> calls and close calls on returned <em>Connections<\/em> will behave properly within a transaction, i.e. always operate on the transactional Connection. If not within a transaction, normal <em>DataSource<\/em> behavior applies.<\/p>\n<\/blockquote>\n<p>In other words, if you perform multiple complex operations without a transaction, jOOQ will use a different connection for each operation. This can lead into race condition bugs.<\/p>\n<p>I noticed this issue when I read this <a href=\"https:\/\/github.com\/jOOQ\/jOOQ\/issues\/1836#issuecomment-19468504\" target=\"_blank\">comment written by Ben Manes<\/a>.<\/p>\n<p><strong>2. Using <em>TransactionAwareDataSourceProxy<\/em> is not recommend by its Javadoc.<\/strong><\/p>\n<p>The <a href=\"http:\/\/docs.spring.io\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/jdbc\/datasource\/TransactionAwareDataSourceProxy.html\" target=\"_blank\">Javadoc of the <em>TransactionAwareDataSourceProxy<\/em><\/a> class has a section which goes like this:<\/p>\n<p>This proxy allows data access code to work with the plain JDBC API and still participate in Spring-managed transactions, similar to JDBC code in a J2EE\/JTA environment. However, if possible, use Spring\u2019s <em>DataSourceUtils<\/em>, <em>JdbcTemplate<\/em> or JDBC operation objects to get transaction participation even without a proxy for the target <em>DataSource<\/em>, avoiding the need to define such a proxy in the first place.<\/p>\n<p>That is a pretty vague comment because it offers no explanation why we shouldn\u2019t use it. <a href=\"https:\/\/github.com\/jOOQ\/jOOQ\/issues\/1836#issuecomment-19491217\" target=\"_blank\">Adam Zell suggested<\/a> that because the class uses reflection, using it might cause performance problems.<\/p>\n<p>If you run in performance problems, you might want to use the approach described in<br \/>\n<a href=\"https:\/\/gist.github.com\/azell\/5655888\" target=\"_blank\">Adam Zell\u2019s Gist<\/a>.<\/p>\n<h2>Summary<\/h2>\n<p>We have now successfully configured the application context of our example application. This tutorial has taught four things:<\/p>\n<ul>\n<li>We learned how we can get the required dependencies with Maven.<\/li>\n<li>We learned how we can transform the exceptions thrown by jOOQ to Spring <em>DataAccessExceptions<\/em>.<\/li>\n<li>We learned how we can configure the application context of an application which uses jOOQ and Spring.<\/li>\n<li>We took a quick at the things that we have to take into account when we are using the approach described in this blog post.<\/li>\n<\/ul>\n<p>The next part of this tutorial describes we can use the <a href=\"\/programming\/jooq\/using-jooq-with-spring-code-generation\/\" target=\"_blank\">code generation support of jOOQ<\/a>.<\/p>\n<p>The example application of this blog post is available <a href=\"https:\/\/github.com\/pkainulainen\/jooq-with-spring-examples\/tree\/master\/configuration\" target=\"_blank\">at Github<\/a>.<\/p>\n<p><strong>Additional reading:<\/strong><\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/2013\/12\/hibernate-facts-always-check-criteria-api-sql-queries.html\" target=\"_blank\">Vlad Mihalcea has written about jOOQ<\/a> as well. Check out his blog!<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/www.petrikainulainen.net\/programming\/jooq\/using-jooq-with-spring-configuration\/\">Using jOOQ with Spring: Configuration<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Petri Kainulainen at the <a href=\"http:\/\/www.petrikainulainen.net\/\">Petri Kainulainen<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>I have had my share of performance problems caused by ORMs. Although I have to admit that most of these problems were really caused by yours truly, I have started to think that using ORMs in read-only operations is not worth it. I started to look for alternative ways to implement these operations. That is &hellip;<\/p>\n","protected":false},"author":429,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[256,30],"class_list":["post-20557","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-jooq","tag-spring"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Using jOOQ with Spring: Configuration<\/title>\n<meta name=\"description\" content=\"I have had my share of performance problems caused by ORMs. Although I have to admit that most of these problems were really caused by yours truly, I have\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using jOOQ with Spring: Configuration\" \/>\n<meta property=\"og:description\" content=\"I have had my share of performance problems caused by ORMs. Although I have to admit that most of these problems were really caused by yours truly, I have\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2014-01-27T23:00:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Petri Kainulainen\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/petrikainulaine\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Petri Kainulainen\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html\"},\"author\":{\"name\":\"Petri Kainulainen\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/5af4df3fdfeb79e9fa3598d79bff2c9e\"},\"headline\":\"Using jOOQ with Spring: Configuration\",\"datePublished\":\"2014-01-27T23:00:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html\"},\"wordCount\":1881,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"jOOQ\",\"Spring\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html\",\"name\":\"Using jOOQ with Spring: Configuration\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2014-01-27T23:00:46+00:00\",\"description\":\"I have had my share of performance problems caused by ORMs. Although I have to admit that most of these problems were really caused by yours truly, I have\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/using-jooq-with-spring-configuration.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Using jOOQ with Spring: Configuration\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/5af4df3fdfeb79e9fa3598d79bff2c9e\",\"name\":\"Petri Kainulainen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g\",\"caption\":\"Petri Kainulainen\"},\"description\":\"Petri is passionate about software development and continuous improvement. He is specialized in software development with the Spring Framework and is the author of Spring Data book.\",\"sameAs\":[\"http:\\\/\\\/www.petrikainulainen.net\\\/\",\"http:\\\/\\\/www.linkedin.com\\\/in\\\/petrikainulainen\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/petrikainulaine\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/petri-kainulainen\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using jOOQ with Spring: Configuration","description":"I have had my share of performance problems caused by ORMs. Although I have to admit that most of these problems were really caused by yours truly, I have","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html","og_locale":"en_US","og_type":"article","og_title":"Using jOOQ with Spring: Configuration","og_description":"I have had my share of performance problems caused by ORMs. Although I have to admit that most of these problems were really caused by yours truly, I have","og_url":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2014-01-27T23:00:46+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Petri Kainulainen","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/petrikainulaine","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Petri Kainulainen","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html"},"author":{"name":"Petri Kainulainen","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/5af4df3fdfeb79e9fa3598d79bff2c9e"},"headline":"Using jOOQ with Spring: Configuration","datePublished":"2014-01-27T23:00:46+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html"},"wordCount":1881,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["jOOQ","Spring"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html","url":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html","name":"Using jOOQ with Spring: Configuration","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2014-01-27T23:00:46+00:00","description":"I have had my share of performance problems caused by ORMs. Although I have to admit that most of these problems were really caused by yours truly, I have","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/using-jooq-with-spring-configuration.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Using jOOQ with Spring: Configuration"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/5af4df3fdfeb79e9fa3598d79bff2c9e","name":"Petri Kainulainen","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g","caption":"Petri Kainulainen"},"description":"Petri is passionate about software development and continuous improvement. He is specialized in software development with the Spring Framework and is the author of Spring Data book.","sameAs":["http:\/\/www.petrikainulainen.net\/","http:\/\/www.linkedin.com\/in\/petrikainulainen","https:\/\/x.com\/https:\/\/twitter.com\/petrikainulaine"],"url":"https:\/\/www.javacodegeeks.com\/author\/petri-kainulainen"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/20557","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/429"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=20557"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/20557\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=20557"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=20557"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=20557"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}