在 jooq 中使用 DAO 时出现 DataAccessException
Posted
技术标签:
【中文标题】在 jooq 中使用 DAO 时出现 DataAccessException【英文标题】:DataAccessException when using DAO in jooq 【发布时间】:2020-02-21 06:41:11 【问题描述】:我想使用 DAO 将 Generated Pojo 添加到数据库中。 但是我收到一个异常并且不知道如何解决它。
我尝试在每个 Table 前面添加一个 Public.Troop。
将部队插入 DAO 用法:
TroopDao dao = new TroopDao(new DefaultConfiguration().set(SQLDialect.SQLITE).set(database.getConnection()));
Troop initial = new Troop(1, 100, 120, 120.2, 11.2, 12.0, 13.0, 6245.0, 1534.0, 1364.0, 121235.3, 125.3, 51.3);
dao.insert(initial);
使用的数据库文件:
CREATE TABLE IF NOT EXISTS TROOP(
id INTEGER PRIMARY KEY AUTOINCREMENT,
current_health INTEGER NOT NULL,
max_health INTEGER NOT NULL,
pos_x DOUBLE NOT NULL,
pos_y DOUBLE NOT NULL,
normal_speed DOUBLE NOT NULL,
street_speed DOUBLE NOT NULL,
difficult_terrain_speed DOUBLE NOT NULL,
close_combat_range DOUBLE NOT NULL,
ranged_combat_range DOUBLE NOT NULL,
normal_view_distance DOUBLE NOT NULL,
disadvantaged_view_distance DOUBLE NOT NULL,
advantaged_view_distance DOUBLE NOT NULL
);
CREATE TABLE IF NOT EXISTS ARMY(
id INTEGER,
hq INTEGER,
troop INTEGER,
FOREIGN KEY(hq) REFERENCES TROOP(id),
FOREIGN KEY(troop) REFERENCES TROOP(id),
UNIQUE(hq, troop),
PRIMARY KEY (id, hq, troop)
);
JOOQ 生成,我也试过 unqualifiedSchema = main:
Configuration configuration = new Configuration()
.withGenerator(new Generator()
.withDatabase(new Database()
.withName("org.jooq.meta.extensions.ddl.DDLDatabase")
.withIncludes("ARMY | TROOP")
.withOutputSchemaToDefault(Boolean.TRUE)
.withProperties(new Property()
.withKey("unqualifiedSchema")
.withValue("none"),
new Property()
.withKey("scripts")
.withValue("/db/schema.sql")))
.withGenerate(new Generate()
.withPojos(Boolean.TRUE)
.withDeprecationOnUnknownTypes(Boolean.FALSE)
.withImmutableInterfaces(Boolean.TRUE)
.withDaos(Boolean.TRUE))
.withTarget(new Target()
.withPackageName("me.leslie.generals.server.persistence.jooq")
.withDirectory("Generals-Server/src/main/java")));
GenerationTool.generate(configuration);
Databaseclass 只是一个返回基本 DataBaseconnection 的单例:
@EqualsAndHashCode
@ToString
@Getter
public class Database
public static final String DEFAULT_DB_URL = "jdbc:sqlite:";
@NonNull
private final String url;
private final Connection connection;
private static Database instance;
public static Database get()
if(instance == null)
instance = new Database(DEFAULT_DB_URL);
return instance;
private Database(String url)
try
this.connection = DriverManager.getConnection(url);
catch (SQLException e)
throw new InitializationException("Could not get Database connection", e);
initialize();
this.url = url;
private void initialize()
final String troopSchema = "CREATE TABLE IF NOT EXISTS TROOP(" +
"id INTEGER PRIMARY KEY AUTOINCREMENT," +
"current_health INTEGER NOT NULL," +
"max_health INTEGER NOT NULL," +
"pos_x DOUBLE NOT NULL," +
"pos_y DOUBLE NOT NULL," +
"normal_speed DOUBLE NOT NULL," +
"street_speed DOUBLE NOT NULL," +
"difficult_terrain_speed DOUBLE NOT NULL," +
"close_combat_range DOUBLE NOT NULL," +
"ranged_combat_range DOUBLE NOT NULL," +
"normal_view_distance DOUBLE NOT NULL," +
"disadvantaged_view_distance DOUBLE NOT NULL," +
"advantaged_view_distance DOUBLE NOT NULL" +
");";
final String armySchema = "CREATE TABLE IF NOT EXISTS ARMY(" +
"id INTEGER," +
"hq INTEGER," +
"troop INTEGER," +
"FOREIGN KEY(hq) REFERENCES TROOP(id)," +
"FOREIGN KEY(troop) REFERENCES TROOP(id)," +
"UNIQUE(hq, troop)," +
"PRIMARY KEY (id, hq, troop)" +
");";
try (PreparedStatement sql = connection.prepareStatement(troopSchema))
sql.execute();
catch (SQLException e)
throw new InitializationException("Could not initialize Troops", e);
try (PreparedStatement sql = connection.prepareStatement(armySchema))
sql.execute();
catch (SQLException e)
throw new InitializationException("Could not initialize Armies", e);
错误,当我使用基于文件的数据库并访问它时,所需的表似乎在那里:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.jooq.tools.reflect.Reflect (file:/home/leslie/.m2/repository/org/jooq/jooq/3.11.11/jooq-3.11.11.jar) to constructor java.lang.invoke.MethodHandles$Lookup(java.lang.Class)
WARNING: Please consider reporting this to the maintainers of org.jooq.tools.reflect.Reflect
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
23:32:56.084 [main] INFO org.jooq.Constants -
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@ @@ @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@
@@@@@@@@@@@@@@@@ @@ @@ @@@@@@@@@@
@@@@@@@@@@ @@@@ @@ @@ @@@@@@@@@@
@@@@@@@@@@ @@ @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@ @@ @@@@@@@@@@
@@@@@@@@@@ @@ @@ @@@@ @@@@@@@@@@
@@@@@@@@@@ @@ @@ @@@@ @@@@@@@@@@
@@@@@@@@@@ @@ @ @ @@@@@@@@@@
@@@@@@@@@@ @@ @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Thank you for using jOOQ 3.11.11
23:32:56.093 [main] DEBUG org.jooq.tools.LoggerListener - Executing query : select PUBLIC.TROOP.ID from PUBLIC.TROOP
23:32:56.099 [main] DEBUG org.jooq.tools.LoggerListener - Exception
org.jooq.exception.DataAccessException: SQL [select PUBLIC.TROOP.ID from PUBLIC.TROOP]; [SQLITE_ERROR] SQL error or missing database (no such table: PUBLIC.TROOP)
at org.jooq_3.11.11.SQLITE.debug(Unknown Source)
at org.jooq.impl.Tools.translate(Tools.java:2430)
at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:832)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:364)
at org.jooq.impl.AbstractResultQuery.fetch(AbstractResultQuery.java:323)
at org.jooq.impl.SelectImpl.fetch(SelectImpl.java:2700)
at me.leslie.generals.server.repository.TroopJooqRepository.nextID(TroopJooqRepository.java:47)
at me.leslie.generals.server.repository.TroopJooqRepository.create(TroopJooqRepository.java:60)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at org.jooq.lambda.SeqImpl.collect(SeqImpl.java:190)
at me.leslie.generals.server.repository.TroopJooqRepositoryTest.initializeTroops(TroopJooqRepositoryTest.java:38)
at me.leslie.generals.server.repository.TroopJooqRepositoryTest.getSomeTroops(TroopJooqRepositoryTest.java:152)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
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)
Caused by: org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (no such table: PUBLIC.TROOP)
at org.sqlite.core.DB.newSQLException(DB.java:941)
at org.sqlite.core.DB.newSQLException(DB.java:953)
at org.sqlite.core.DB.throwex(DB.java:918)
at org.sqlite.core.NativeDB.prepare_utf8(Native Method)
at org.sqlite.core.NativeDB.prepare(NativeDB.java:134)
at org.sqlite.core.DB.prepare(DB.java:257)
at org.sqlite.core.CorePreparedStatement.<init>(CorePreparedStatement.java:47)
at org.sqlite.jdbc3.JDBC3PreparedStatement.<init>(JDBC3PreparedStatement.java:30)
at org.sqlite.jdbc4.JDBC4PreparedStatement.<init>(JDBC4PreparedStatement.java:19)
at org.sqlite.jdbc4.JDBC4Connection.prepareStatement(JDBC4Connection.java:35)
at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:241)
at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:205)
at org.jooq.impl.ProviderEnabledConnection.prepareStatement(ProviderEnabledConnection.java:109)
at org.jooq.impl.SettingsEnabledConnection.prepareStatement(SettingsEnabledConnection.java:73)
at org.jooq.impl.AbstractResultQuery.prepare(AbstractResultQuery.java:239)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:322)
... 77 common frames omitted
【问题讨论】:
【参考方案1】:根据 jOOQ 3.12,DDLDatabase
解析您的 SQL 脚本,将它们转换为 H2 并针对内存中的 H2 数据库运行它们,该数据库使用 PUBLIC
作为默认架构,您的所有表现在都位于代码生成器的观点。
这样的架构在 SQLite 中不存在,这就是为什么您会收到您所看到的错误。 jOOQ 3.12 通过支持新的unqualifiedSchema
属性解决了这个问题,该属性允许在 DDL 脚本中指定所有不合格表的隐含模式。默认情况下,假设这映射到 H2 中的 PUBLIC
,PUBLIC
被假定为“默认模式”。因此,要解决此问题,只需升级到 jOOQ 3.12。在此处查看更多详细信息:
https://www.jooq.org/doc/latest/manual/code-generation/codegen-ddl
注意:您已经在使用此标志,但您没有使用 jOOQ 3.12。 3.11.11 还没有。
【讨论】:
以上是关于在 jooq 中使用 DAO 时出现 DataAccessException的主要内容,如果未能解决你的问题,请参考以下文章
通过 JOOQ-meta 访问 H2 元模型时出现 SQLException
使用 jOOQ 和 Spring Boot 进行集成测试时出现“PSQLException: FATAL: sorry, too many clients already”错误