我有jOOQ(3.11.11)+ H2 + Spring应用程序,其中我试图运行一个简单的JUnit测试以实现持久性,但是没有例外。
这是我的application.properties
文件:
spring.datasource.url=jdbc:h2:mem:jooq-test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL
spring.datasource.platform=h2
spring.datasource.username = sa
spring.datasource.password =
我的测试配置类为:
@Configuration
public class DummyTestConfig {
@Bean
public DSLContext dsl() {
return DSL.using(SQLDialect.H2);
}
}
还有我的测试用例:
public class JooqRepositoryImplTest {
@MockBean
private PlatformCache platformCache;
@Autowired
private JooqRepositoryImpl JooqRepository;
private List<Entity> getDummyEntityList() {
List<Entity> data = new ArrayList<>();
for (int i = 0; i < 15; i++) {
data.add(getDummyEntity());
}
return data;
}
private Entity getDummyEntity() {
final Entity entity = new Entity();
entity.setCapacity(150);
return entity;
}
@Test
public void testDatabaseIsUp() {
assert(1 == JooqRepository.count());
}
@Test
public void testReplace() {
JooqRepository.getEntitiesByJDBC(124, "C", DirectionEnum.I, TrafficBucketEnum.D);
}
@Test
public void testSave() {
final List<Entity> data = getDummyEntityList();
JooqRepository.batchSaveByJDBC(data);
}
}
我的存储库实现
@Repository
public class JooqRepositoryImpl implements CustomRepository {
@Autowired
private DSLContext dslContext;
public int count() {
return dslContext.fetchCount(MyTable.MY_TABLE);
}
@Transactional
@Override
public void batchSaveByJDBC(List<Entity> entities) {
dslContext.batchInsert(entities.parallelStream().map(convertEntityToRecord()).collect(Collectors.toList()));
}
private Function<Entity, Record> convertEntityToRecord() {
return entity -> {
final Record record = new Record();
record.setCapacity(entity.getCapacity());
return record;
};
}
@Override
public void batchReplaceByJDBC(List<Entity> entities) {
executeReplace(MyTable.MY_TABLE, entities.toArray());
}
public int executeReplace(Table<Record> table, Object[] values) {
return dslContext.execute("replace into {0} ({1}) values ({2})",
table,
dslContext.informationSchema(table).getColumns(),
DSL.list(Stream.of(values).map(DSL::val).collect(Collectors.toList()))
);
}
@Override
public void batchUpdateByJDBC(List<Entity> entities,
LegRoutingTO leg) {
dslContext.batchUpdate(entities.parallelStream().map(convertEntityToRecord()).collect(Collectors.toList()));
}
@Override
public void batchUpdateByJDBCPartial (
List<Entity> entities, LegRoutingTO leg) {
final Batch updates = dslContext.batch(
entities.parallelStream().map(convertEntityToRecord()).map(convertRecordToQuery()).collect(Collectors.toList()));
updates.execute();
}
private Function<Record, Query> convertRecordToQuery() {
return record -> {
final UpdateQuery<Record> query = dslContext.updateQuery(MyTable.MY_TABLE);
query.setRecord(record);
return query;
};
}
private Function<Record, Entity> convertRecordToEntity() {
return record -> {
final Entity entity = new Entity();
BeanUtils.copyProperties(record, entity);
return entity;
};
}
}
编辑:我的pom.xml
:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.5</version>
<!-- Skip DB creation if the value of the skip.db.creation property is
true -->
<configuration>
<skip>${skip.db.creation}</skip>
</configuration>
<executions>
<!-- Execute SQL statements to the configured database -->
<execution>
<id>create-database-h2</id>
<phase>generate-sources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<!-- Configure the database connection -->
<driver>org.h2.Driver</driver>
<url>jdbc:h2:~/sampledb;INIT=CREATE SCHEMA IF NOT EXISTS
sampledb</url>
<username>sa</username>
<password></password>
<!-- Ensure that our changes are committed automatically -->
<autocommit>true</autocommit>
<!-- Configure the location of the invoked SQL script -->
<srcFiles>
<srcFile>src/main/resources/schema.sql</srcFile>
</srcFiles>
</configuration>
</execution>
</executions>
<dependencies>
<!-- Because we use the H2 database, we have to add it as the dependency
of this plugin. -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${com.h2database.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>3.4.4</version>
<executions>
<!-- Generate the required class from the database -->
<execution>
<id>generate-h2</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<!-- Because we use the H2 database, we have to add it as the dependency
of this plugin. -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${com.h2database.version}</version>
</dependency>
</dependencies>
<configuration>
<!-- Configure the database connection -->
<jdbc>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:~/sampledb;INIT=CREATE SCHEMA IF NOT EXISTS
FORECAST_MEASURES</url>
<user>sa</user>
<password></password>
</jdbc>
<generator>
<database>
<!-- Configure the used database dialect -->
<name>org.jooq.util.h2.H2Database</name>
<!-- Include all tables found from the PUBLIC schema -->
<includes>.*</includes>
<excludes></excludes>
<inputSchema>PUBLIC</inputSchema>
</database>
<!-- Generate classes for tables and records -->
<generate>
<records>true</records>
</generate>
<!-- Configure the target package and dirmectory -->
<target>
<packageName>com.xxxx.entity.jooq</packageName>
<directory>src/main/java</directory>
</target>
</generator>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.codehaus.mojo
</groupId>
<artifactId>
sql-maven-plugin
</artifactId>
<versionRange>
[1.5,)
</versionRange>
<goals>
<goal>execute</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
----------
当我尝试运行测试用例时,其中一个通过(testBatchInsert),而另外两个则失败,并带有以下堆栈跟踪:
org.jooq.exception.DetachedException: Cannot execute query. No Connection configured
at org.jooq_3.11.11.H2.debug(Unknown Source)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:319)
at org.jooq.impl.AbstractResultQuery.fetchLazy(AbstractResultQuery.java:393)
at org.jooq.impl.AbstractResultQuery.fetchLazy(AbstractResultQuery.java:380)
at org.jooq.impl.AbstractResultQuery.fetchStream(AbstractResultQuery.java:351)
at org.jooq.impl.SelectImpl.fetchStream(SelectImpl.java:2716)
at com.xxxx.repository.implementation.JooqRepositoryImpl.getEntitiesByJDBC(JooqRepositoryImpl.java:159)
at com.xxxx.repository.implementation.JooqRepositoryImpl$$FastClassBySpringCGLIB$$8ff9f08.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
at com.xxxx.repository.implementation.JooqRepositoryImpl$$EnhancerBySpringCGLIB$$923a185d.getEntitiesByJDBC(<generated>)
at com.xxxx.repository.implementation.JooqRepositoryImplTest.testReplace(JooqRepositoryImplTest.java:126)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:66)
答案 0 :(得分:0)
原因是您的DSLContext
配置:
@Configuration
public class DummyTestConfig {
@Bean
public DSLContext dsl() {
return DSL.using(SQLDialect.H2);
}
}
它未连接到您的数据源。要么,您需要将数据源注入此配置,然后使用它:
@Configuration
public class DummyTestConfig {
@Autowired
DataSource ds;
@Bean
public DSLContext dsl() {
return DSL.using(ds, SQLDialect.H2);
}
}
或者您根本不执行此操作,而是使用Spring Boot注入的DSLContext
。将此添加到您的application.properties
文件中:
#jOOQ Configuration
spring.jooq.sql-dialect=H2
您可以在此处找到示例项目:https://github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/jOOQ-spring-boot-example