Add support for jOOQ
Add auto-configuration and a starter POM for jOOQ. See gh-2804
This commit is contained in:
parent
9da14fe62a
commit
a08b09563b
|
@ -510,6 +510,11 @@
|
|||
<artifactId>aspectjweaver</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- Annotation processing -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jooq;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.jooq.ConnectionProvider;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.ExecuteListenerProvider;
|
||||
import org.jooq.RecordListenerProvider;
|
||||
import org.jooq.RecordMapperProvider;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.TransactionProvider;
|
||||
import org.jooq.VisitListenerProvider;
|
||||
import org.jooq.conf.Settings;
|
||||
import org.jooq.impl.DataSourceConnectionProvider;
|
||||
import org.jooq.impl.DefaultConfiguration;
|
||||
import org.jooq.impl.DefaultDSLContext;
|
||||
import org.jooq.impl.DefaultExecuteListenerProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for JOOQ.
|
||||
*
|
||||
* @author Andreas Ahlenstorf
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(DSLContext.class)
|
||||
@ConditionalOnBean(DataSource.class)
|
||||
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
|
||||
public class JooqAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(DataSourceConnectionProvider.class)
|
||||
public DataSourceConnectionProvider dataSourceConnectionProvider(DataSource dataSource) {
|
||||
return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(
|
||||
dataSource));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(PlatformTransactionManager.class)
|
||||
public TransactionProvider transactionProvider(PlatformTransactionManager txManager) {
|
||||
return new SpringTransactionProvider(txManager);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExecuteListenerProvider jooqExceptionTranslatorExecuteListenerProvider() {
|
||||
return new DefaultExecuteListenerProvider(new JooqExceptionTranslator());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(DSLContext.class)
|
||||
@EnableConfigurationProperties(JooqProperties.class)
|
||||
public static class DslContextConfiguration {
|
||||
|
||||
@Autowired
|
||||
private JooqProperties properties = new JooqProperties();
|
||||
|
||||
@Autowired
|
||||
private ConnectionProvider connectionProvider;
|
||||
|
||||
@Autowired(required = false)
|
||||
private TransactionProvider transactionProvider;
|
||||
|
||||
@Autowired(required = false)
|
||||
private RecordMapperProvider recordMapperProvider;
|
||||
|
||||
@Autowired(required = false)
|
||||
private Settings settings;
|
||||
|
||||
@Autowired(required = false)
|
||||
private RecordListenerProvider[] recordListenerProviders;
|
||||
|
||||
@Autowired
|
||||
private ExecuteListenerProvider[] executeListenerProviders;
|
||||
|
||||
@Autowired(required = false)
|
||||
private VisitListenerProvider[] visitListenerProviders;
|
||||
|
||||
@Bean
|
||||
public DefaultDSLContext dslContext(org.jooq.Configuration configuration) {
|
||||
return new DefaultDSLContext(configuration);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(org.jooq.Configuration.class)
|
||||
public DefaultConfiguration jooqConfiguration() {
|
||||
DefaultConfiguration configuration = new DefaultConfiguration();
|
||||
if (!StringUtils.isEmpty(this.properties.getSqlDialect())) {
|
||||
configuration.set(SQLDialect.valueOf(this.properties.getSqlDialect()));
|
||||
}
|
||||
configuration.set(this.connectionProvider);
|
||||
if (this.transactionProvider != null) {
|
||||
configuration.set(this.transactionProvider);
|
||||
}
|
||||
if (this.recordMapperProvider != null) {
|
||||
configuration.set(this.recordMapperProvider);
|
||||
}
|
||||
if (this.settings != null) {
|
||||
configuration.set(this.settings);
|
||||
}
|
||||
configuration.set(this.recordListenerProviders);
|
||||
configuration.set(this.executeListenerProviders);
|
||||
configuration.set(this.visitListenerProviders);
|
||||
return configuration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jooq;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.impl.DefaultExecuteListener;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
|
||||
import org.springframework.jdbc.support.SQLExceptionTranslator;
|
||||
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
|
||||
|
||||
/**
|
||||
* Transforms {@link java.sql.SQLException} into a Spring-specific @{link
|
||||
* DataAccessException}.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* @author Andreas Ahlenstorf
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class JooqExceptionTranslator extends DefaultExecuteListener {
|
||||
|
||||
// Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JooqExceptionTranslator.class);
|
||||
|
||||
@Override
|
||||
public void exception(ExecuteContext context) {
|
||||
SQLExceptionTranslator translator = getTranslator(context);
|
||||
// The exception() callback is not only triggered for SQL exceptions but also for
|
||||
// "normal" exceptions. In those cases sqlException() returns null.
|
||||
SQLException exception = context.sqlException();
|
||||
while (exception != null) {
|
||||
handle(context, translator, exception);
|
||||
exception = exception.getNextException();
|
||||
}
|
||||
}
|
||||
|
||||
private SQLExceptionTranslator getTranslator(ExecuteContext context) {
|
||||
SQLDialect dialect = context.configuration().dialect();
|
||||
if (dialect != null) {
|
||||
return new SQLErrorCodeSQLExceptionTranslator(dialect.name());
|
||||
}
|
||||
return new SQLStateSQLExceptionTranslator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a single exception in the chain. SQLExceptions might be nested multiple
|
||||
* levels deep. The outermost exception is usually the least interesting one
|
||||
* ("Call getNextException to see the cause."). Therefore the innermost exception is
|
||||
* propagated and all other exceptions are logged.
|
||||
* @param context the execute context
|
||||
* @param translator the exception translator
|
||||
* @param exception the exception
|
||||
*/
|
||||
private void handle(ExecuteContext context, SQLExceptionTranslator translator,
|
||||
SQLException exception) {
|
||||
DataAccessException translated = translate(context, translator, exception);
|
||||
if (exception.getNextException() == null) {
|
||||
context.exception(translated);
|
||||
}
|
||||
else {
|
||||
logger.error("Execution of SQL statement failed.", translated);
|
||||
}
|
||||
}
|
||||
|
||||
private DataAccessException translate(ExecuteContext context,
|
||||
SQLExceptionTranslator translator, SQLException exception) {
|
||||
return translator.translate("jOOQ", context.sql(), exception);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jooq;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for the JOOQ database library.
|
||||
*
|
||||
* @author Andreas Ahlenstorf
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.jooq")
|
||||
public class JooqProperties {
|
||||
|
||||
/**
|
||||
* SQLDialect JOOQ used when communicating with the configured datasource, e.g.
|
||||
* "POSTGRES".
|
||||
*/
|
||||
private String sqlDialect;
|
||||
|
||||
public String getSqlDialect() {
|
||||
return this.sqlDialect;
|
||||
}
|
||||
|
||||
public void setSqlDialect(String sqlDialect) {
|
||||
this.sqlDialect = sqlDialect;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jooq;
|
||||
|
||||
import org.jooq.Transaction;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
|
||||
/**
|
||||
* Adapts a Spring transaction for JOOQ.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* @author Andreas Ahlenstorf
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class SpringTransaction implements Transaction {
|
||||
|
||||
// Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
|
||||
|
||||
private final TransactionStatus transactionStatus;
|
||||
|
||||
public SpringTransaction(TransactionStatus transactionStatus) {
|
||||
this.transactionStatus = transactionStatus;
|
||||
}
|
||||
|
||||
public TransactionStatus getTxStatus() {
|
||||
return this.transactionStatus;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jooq;
|
||||
|
||||
import org.jooq.TransactionContext;
|
||||
import org.jooq.TransactionProvider;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
|
||||
/**
|
||||
* Allows Spring Transaction to be used with JOOQ.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* @author Andreas Ahlenstorf
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class SpringTransactionProvider implements TransactionProvider {
|
||||
|
||||
// Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ
|
||||
|
||||
private final PlatformTransactionManager transactionManager;
|
||||
|
||||
SpringTransactionProvider(PlatformTransactionManager transactionManager) {
|
||||
this.transactionManager = transactionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(TransactionContext context) {
|
||||
TransactionDefinition definition = new DefaultTransactionDefinition(
|
||||
TransactionDefinition.PROPAGATION_NESTED);
|
||||
TransactionStatus status = this.transactionManager.getTransaction(definition);
|
||||
context.transaction(new SpringTransaction(status));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit(TransactionContext ctx) {
|
||||
this.transactionManager.commit(getTransactionStatus(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback(TransactionContext ctx) {
|
||||
this.transactionManager.rollback(getTransactionStatus(ctx));
|
||||
}
|
||||
|
||||
private TransactionStatus getTransactionStatus(TransactionContext ctx) {
|
||||
SpringTransaction transaction = (SpringTransaction) ctx.transaction();
|
||||
return transaction.getTxStatus();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for JOOQ.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.jooq;
|
|
@ -39,6 +39,7 @@ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchDataAutoConfig
|
|||
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
|
||||
|
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jooq;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.ExecuteListener;
|
||||
import org.jooq.ExecuteListenerProvider;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordListener;
|
||||
import org.jooq.RecordListenerProvider;
|
||||
import org.jooq.RecordMapper;
|
||||
import org.jooq.RecordMapperProvider;
|
||||
import org.jooq.RecordType;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.TransactionalRunnable;
|
||||
import org.jooq.VisitListener;
|
||||
import org.jooq.VisitListenerProvider;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link JooqAutoConfiguration}.
|
||||
*
|
||||
* @author Andreas Ahlenstorf
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class JooqAutoConfigurationTests {
|
||||
|
||||
private static final String[] NO_BEANS = {};
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"spring.datasource.name:jooqtest");
|
||||
EnvironmentTestUtils.addEnvironment(this.context, "spring.jooq.sql-dialect:H2");
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noDataSource() throws Exception {
|
||||
registerAndRefresh(JooqAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
assertEquals(0, this.context.getBeanNamesForType(DSLContext.class).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jooqWithoutTx() throws Exception {
|
||||
registerAndRefresh(JooqDataSourceConfiguration.class,
|
||||
JooqAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
|
||||
assertThat(getBeanNames(PlatformTransactionManager.class), equalTo(NO_BEANS));
|
||||
assertThat(getBeanNames(SpringTransactionProvider.class), equalTo(NO_BEANS));
|
||||
DSLContext dsl = this.context.getBean(DSLContext.class);
|
||||
dsl.execute("create table jooqtest (name varchar(255) primary key);");
|
||||
dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;",
|
||||
equalTo("0")));
|
||||
dsl.transaction(new ExecuteSql(dsl, "insert into jooqtest (name) values ('foo');"));
|
||||
dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;",
|
||||
equalTo("1")));
|
||||
try {
|
||||
dsl.transaction(new ExecuteSql(dsl,
|
||||
"insert into jooqtest (name) values ('bar');",
|
||||
"insert into jooqtest (name) values ('foo');"));
|
||||
fail("An DataIntegrityViolationException should have been thrown.");
|
||||
}
|
||||
catch (DataIntegrityViolationException ex) {
|
||||
}
|
||||
dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;",
|
||||
equalTo("2")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jooqWithTx() throws Exception {
|
||||
registerAndRefresh(JooqDataSourceConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, TxManagerConfiguration.class,
|
||||
JooqAutoConfiguration.class);
|
||||
this.context.getBean(PlatformTransactionManager.class);
|
||||
DSLContext dsl = this.context.getBean(DSLContext.class);
|
||||
assertEquals(SQLDialect.H2, dsl.configuration().dialect());
|
||||
dsl.execute("create table jooqtest_tx (name varchar(255) primary key);");
|
||||
dsl.transaction(new AssertFetch(dsl,
|
||||
"select count(*) as total from jooqtest_tx;", equalTo("0")));
|
||||
dsl.transaction(new ExecuteSql(dsl,
|
||||
"insert into jooqtest_tx (name) values ('foo');"));
|
||||
dsl.transaction(new AssertFetch(dsl,
|
||||
"select count(*) as total from jooqtest_tx;", equalTo("1")));
|
||||
try {
|
||||
dsl.transaction(new ExecuteSql(dsl,
|
||||
"insert into jooqtest (name) values ('bar');",
|
||||
"insert into jooqtest (name) values ('foo');"));
|
||||
fail("A DataIntegrityViolationException should have been thrown.");
|
||||
}
|
||||
catch (DataIntegrityViolationException ex) {
|
||||
}
|
||||
dsl.transaction(new AssertFetch(dsl,
|
||||
"select count(*) as total from jooqtest_tx;", equalTo("1")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customProvidersArePickedUp() {
|
||||
registerAndRefresh(JooqDataSourceConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, TxManagerConfiguration.class,
|
||||
TestRecordMapperProvider.class, TestRecordListenerProvider.class,
|
||||
TestExecuteListenerProvider.class, TestVisitListenerProvider.class,
|
||||
JooqAutoConfiguration.class);
|
||||
DSLContext dsl = this.context.getBean(DSLContext.class);
|
||||
assertEquals(TestRecordMapperProvider.class, dsl.configuration()
|
||||
.recordMapperProvider().getClass());
|
||||
assertThat(dsl.configuration().recordListenerProviders().length, equalTo(1));
|
||||
assertThat(dsl.configuration().executeListenerProviders().length, equalTo(2));
|
||||
assertThat(dsl.configuration().visitListenerProviders().length, equalTo(1));
|
||||
}
|
||||
|
||||
private void registerAndRefresh(Class<?>... annotatedClasses) {
|
||||
this.context.register(annotatedClasses);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
private String[] getBeanNames(Class<?> type) {
|
||||
return this.context.getBeanNamesForType(type);
|
||||
}
|
||||
|
||||
private static class AssertFetch implements TransactionalRunnable {
|
||||
|
||||
private final DSLContext dsl;
|
||||
|
||||
private final String sql;
|
||||
|
||||
private final Matcher<? super String> matcher;
|
||||
|
||||
public AssertFetch(DSLContext dsl, String sql, Matcher<? super String> matcher) {
|
||||
this.dsl = dsl;
|
||||
this.sql = sql;
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(org.jooq.Configuration configuration) throws Exception {
|
||||
assertThat(this.dsl.fetch(this.sql).getValue(0, 0).toString(), this.matcher);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ExecuteSql implements TransactionalRunnable {
|
||||
|
||||
private final DSLContext dsl;
|
||||
|
||||
private final String[] sql;
|
||||
|
||||
public ExecuteSql(DSLContext dsl, String... sql) {
|
||||
this.dsl = dsl;
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(org.jooq.Configuration configuration) throws Exception {
|
||||
for (String statement : this.sql) {
|
||||
this.dsl.execute(statement);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class JooqDataSourceConfiguration {
|
||||
|
||||
@Bean
|
||||
public DataSource jooqDataSource() {
|
||||
return DataSourceBuilder.create().url("jdbc:hsqldb:mem:jooqtest")
|
||||
.username("sa").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TxManagerConfiguration {
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager(DataSource dataSource) {
|
||||
return new DataSourceTransactionManager(dataSource);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class TestRecordMapperProvider implements RecordMapperProvider {
|
||||
|
||||
@Override
|
||||
public <R extends Record, E> RecordMapper<R, E> provide(RecordType<R> recordType,
|
||||
Class<? extends E> aClass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class TestRecordListenerProvider implements RecordListenerProvider {
|
||||
|
||||
@Override
|
||||
public RecordListener provide() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class TestExecuteListenerProvider implements ExecuteListenerProvider {
|
||||
|
||||
@Override
|
||||
public ExecuteListener provide() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class TestVisitListenerProvider implements VisitListenerProvider {
|
||||
|
||||
@Override
|
||||
public VisitListener provide() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -100,6 +100,7 @@
|
|||
<joda-time.version>2.8.1</joda-time.version>
|
||||
<jolokia.version>1.3.1</jolokia.version>
|
||||
<json.version>20141113</json.version>
|
||||
<jooq.version>3.6.2</jooq.version>
|
||||
<json-path.version>2.0.0</json-path.version>
|
||||
<jstl.version>1.2</jstl.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
|
@ -318,6 +319,11 @@
|
|||
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||
<version>1.3.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jooq</artifactId>
|
||||
<version>1.3.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
|
||||
|
@ -1477,6 +1483,21 @@
|
|||
<artifactId>json</artifactId>
|
||||
<version>${json.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq</artifactId>
|
||||
<version>${jooq.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq-meta</artifactId>
|
||||
<version>${jooq.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq-codegen</artifactId>
|
||||
<version>${jooq.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-core</artifactId>
|
||||
|
@ -1836,6 +1857,11 @@
|
|||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq-codegen-maven</artifactId>
|
||||
<version>${jooq.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
<module>spring-boot-starter-jdbc</module>
|
||||
<module>spring-boot-starter-jersey</module>
|
||||
<module>spring-boot-starter-jetty</module>
|
||||
<module>spring-boot-starter-jooq</module>
|
||||
<module>spring-boot-starter-jta-atomikos</module>
|
||||
<module>spring-boot-starter-jta-bitronix</module>
|
||||
<module>spring-boot-starter-logging</module>
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starters</artifactId>
|
||||
<version>1.3.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-boot-starter-jooq</artifactId>
|
||||
<name>Spring Boot JOOQ Starter</name>
|
||||
<description>Spring Boot JOOQ Starter</description>
|
||||
<url>http://projects.spring.io/spring-boot/</url>
|
||||
<organization>
|
||||
<name>Pivotal Software, Inc.</name>
|
||||
<url>http://www.spring.io</url>
|
||||
</organization>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
provides: jooq
|
Loading…
Reference in New Issue