jooq java.lang.CastException: java.lang.String 无法转换为 java.lang.Number
jooq java.lang.CastException: java.lang.String cannot be cast to java.lang.Number
在一个项目中,我使用 jklingsporn vertx-jooq 作为 jooq-CodeGenerator 来创建 vertxified DAO 和 POJOS 作为异步。
我有一个生成的 ContractDao.java class
import io.vertx.core.Future;
import io.github.jklingsporn.vertx.jooq.classic.async.AsyncClassicQueryExecutor;
/**
* This class is generated by jOOQ.
*/
@Generated(value = { "http://www.jooq.org", "jOOQ version:3.10.6" }, comments = "This class is generated by jOOQ")
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class ContractDao extends AbstractAsyncVertxDAO<ContractRecord, jooq.tables.pojos.Contract, Long, Future<List<jooq.tables.pojos.Contract>>, Future<jooq.tables.pojos.Contract>, Future<Integer>, Future<Long>> implements io.github.jklingsporn.vertx.jooq.classic.VertxDAO<ContractRecord, jooq.tables.pojos.Contract, Long> {
/**
* @param configuration
* Used for rendering, so only SQLDialect must be set and must be one
* of the MYSQL types or POSTGRES.
* @param delegate
* A configured AsyncSQLClient that is used for query execution
*/
public ContractDao(Configuration configuration, io.vertx.ext.asyncsql.AsyncSQLClient delegate) {
super(Contract.CONTRACT, jooq.tables.pojos.Contract.class, new AsyncClassicQueryExecutor<ContractRecord, jooq.tables.pojos.Contract, Long>(configuration, delegate, jooq.tables.pojos.Contract::new, Contract.CONTRACT));
}
....
}
它使用生成的 Contract.java pojo class 和一个 BigDecimal 字段。
/**
* This class is generated by jOOQ.
*/
@Generated(
value = {
"http://www.jooq.org",
"jOOQ version:3.10.6"
},
comments = "This class is generated by jOOQ"
)
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class Contract implements VertxPojo, IContract {
...
private BigDecimal costValue;
...
}
然后在 vert.x Verticle class 我有一个方法 fetchContracts:
private void fetchContracts(final Message<Void> msg) {
contractDao.findAll().setHandler(arContracts -> {
...
});
}
到目前为止它工作正常,但是如果我在 Table 合同字段 costValue 中有一个数值,当我调用 fetchContracts 方法时我得到一个异常
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
我想可能是某种数据类型不匹配。我已经看到,如果我理解正确的话,这可以通过数据类型强制或强制转换来解决,如下所述:
但在这种特殊情况下,我不清楚应该在何处以及如何执行转换。
我试过类似的方法:
private void fetchContracts(final Message<Void> msg) {
jooq.tables.Contract.CONTRACT.COST_VALUE.coerce(String.class);
contractDao.findAll().setHandler(arContracts -> {
...
});
}
但它不起作用。任何的想法?提前致谢。
已编辑:
我添加堆栈跟踪:
[ERROR] 2018-08-07 09:42:54,368: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number ( de.bfft.licencemgmt.server.UserVerticle.lambda0(UserVerticle.java:998)) [vert.x-eventloop-thread-1] []
[ERROR] 2018-08-07 09:42:54,368: (RECIPIENT_FAILURE,500) java.lang.String cannot be cast to java.lang.Number ( de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda(AgreementsViewLogic.java:61)) [vert.x-eventloop-thread-4] []
[ERROR] 2018-08-07 09:42:54,368: Failed to handleMessage. address: 1 ( io.vertx.core.eventbus.impl.HandlerRegistration.deliver(HandlerRegistration.java:228)) [vert.x-eventloop-thread-4] []
java.lang.NullPointerException: null
at com.vaadin.server.AbstractExtension.extend(AbstractExtension.java:77) ~[vaadin-server-8.4.4.jar:8.4.4]
at com.vaadin.ui.Notification.show(Notification.java:502) ~[vaadin-server-8.4.4.jar:8.4.4]
at de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda[=18=](AgreementsViewLogic.java:39) ~[classes/:?]
at io.vertx.core.impl.FutureImpl.tryFail(FutureImpl.java:165) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.impl.FutureImpl.fail(FutureImpl.java:97) ~[vertx-core-3.5.1.jar:3.5.1]
at de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda(AgreementsViewLogic.java:62) ~[classes/:?]
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$convertHandler(EventBusImpl.java:349) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.HandlerRegistration.deliver(HandlerRegistration.java:223) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.HandlerRegistration.handle(HandlerRegistration.java:200) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$deliverToHandler(EventBusImpl.java:533) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.impl.ContextImpl.lambda$wrapTask(ContextImpl.java:339) ~[vertx-core-3.5.1.jar:3.5.1]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463) [netty-transport-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:886) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_171]
[ERROR] 2018-08-07 09:42:54,383: Unhandled exception ( io.vertx.core.impl.ContextImpl.lambda$wrapTask(ContextImpl.java:345)) [vert.x-eventloop-thread-4] []
java.lang.NullPointerException: null
at com.vaadin.server.AbstractExtension.extend(AbstractExtension.java:77) ~[vaadin-server-8.4.4.jar:8.4.4]
at com.vaadin.ui.Notification.show(Notification.java:502) ~[vaadin-server-8.4.4.jar:8.4.4]
at de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda[=18=](AgreementsViewLogic.java:39) ~[classes/:?]
at io.vertx.core.impl.FutureImpl.tryFail(FutureImpl.java:165) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.impl.FutureImpl.fail(FutureImpl.java:97) ~[vertx-core-3.5.1.jar:3.5.1]
at de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda(AgreementsViewLogic.java:62) ~[classes/:?]
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$convertHandler(EventBusImpl.java:349) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.HandlerRegistration.deliver(HandlerRegistration.java:223) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.HandlerRegistration.handle(HandlerRegistration.java:200) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$deliverToHandler(EventBusImpl.java:533) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.impl.ContextImpl.lambda$wrapTask(ContextImpl.java:339) ~[vertx-core-3.5.1.jar:3.5.1]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463) [netty-transport-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:886) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_171]
而在UserVerticle.javaclass中导致异常的代码,堆栈跟踪中的第998行对应于下面的第三行"log.error(arContracts.cause())":
private void fetchContracts(final Message<Void> msg) {
contractDao.findAll().setHandler(arContracts -> {
if (arContracts.failed()) {
log.error(arContracts.cause());
msg.fail(500, arContracts.cause().getMessage());
return;
}
final List<Contract> contracts = arContracts.result();
log.debug("Found {} contracts", contracts.size());
final JsonArray jsonArray = new JsonArray(
contracts.stream().map(contract -> contract.toJson()).collect(Collectors.toList()));
msg.reply(jsonArray);
});
}
问题出在json中的十进制转换。 Json 自动将十进制数转换为字符串,但它需要一个十进制数,这在某种程度上引发了异常
事实证明,还有一个额外的 CustomVertxGenerator.java class 扩展了 ClassicAsyncVertxGenerator for vert.x-jooq,它有一个方法来处理额外的类型 from/into a String during JSON-转换。这对我来说是新的。
在 class 的方法中修复了 postgresql 数据库中数字类型的转换后,问题就解决了。
在一个项目中,我使用 jklingsporn vertx-jooq 作为 jooq-CodeGenerator 来创建 vertxified DAO 和 POJOS 作为异步。 我有一个生成的 ContractDao.java class
import io.vertx.core.Future;
import io.github.jklingsporn.vertx.jooq.classic.async.AsyncClassicQueryExecutor;
/**
* This class is generated by jOOQ.
*/
@Generated(value = { "http://www.jooq.org", "jOOQ version:3.10.6" }, comments = "This class is generated by jOOQ")
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class ContractDao extends AbstractAsyncVertxDAO<ContractRecord, jooq.tables.pojos.Contract, Long, Future<List<jooq.tables.pojos.Contract>>, Future<jooq.tables.pojos.Contract>, Future<Integer>, Future<Long>> implements io.github.jklingsporn.vertx.jooq.classic.VertxDAO<ContractRecord, jooq.tables.pojos.Contract, Long> {
/**
* @param configuration
* Used for rendering, so only SQLDialect must be set and must be one
* of the MYSQL types or POSTGRES.
* @param delegate
* A configured AsyncSQLClient that is used for query execution
*/
public ContractDao(Configuration configuration, io.vertx.ext.asyncsql.AsyncSQLClient delegate) {
super(Contract.CONTRACT, jooq.tables.pojos.Contract.class, new AsyncClassicQueryExecutor<ContractRecord, jooq.tables.pojos.Contract, Long>(configuration, delegate, jooq.tables.pojos.Contract::new, Contract.CONTRACT));
}
....
}
它使用生成的 Contract.java pojo class 和一个 BigDecimal 字段。
/**
* This class is generated by jOOQ.
*/
@Generated(
value = {
"http://www.jooq.org",
"jOOQ version:3.10.6"
},
comments = "This class is generated by jOOQ"
)
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class Contract implements VertxPojo, IContract {
...
private BigDecimal costValue;
...
}
然后在 vert.x Verticle class 我有一个方法 fetchContracts:
private void fetchContracts(final Message<Void> msg) {
contractDao.findAll().setHandler(arContracts -> {
...
});
}
到目前为止它工作正常,但是如果我在 Table 合同字段 costValue 中有一个数值,当我调用 fetchContracts 方法时我得到一个异常
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
我想可能是某种数据类型不匹配。我已经看到,如果我理解正确的话,这可以通过数据类型强制或强制转换来解决,如下所述:
但在这种特殊情况下,我不清楚应该在何处以及如何执行转换。
我试过类似的方法:
private void fetchContracts(final Message<Void> msg) {
jooq.tables.Contract.CONTRACT.COST_VALUE.coerce(String.class);
contractDao.findAll().setHandler(arContracts -> {
...
});
}
但它不起作用。任何的想法?提前致谢。
已编辑:
我添加堆栈跟踪:
[ERROR] 2018-08-07 09:42:54,368: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number ( de.bfft.licencemgmt.server.UserVerticle.lambda0(UserVerticle.java:998)) [vert.x-eventloop-thread-1] []
[ERROR] 2018-08-07 09:42:54,368: (RECIPIENT_FAILURE,500) java.lang.String cannot be cast to java.lang.Number ( de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda(AgreementsViewLogic.java:61)) [vert.x-eventloop-thread-4] []
[ERROR] 2018-08-07 09:42:54,368: Failed to handleMessage. address: 1 ( io.vertx.core.eventbus.impl.HandlerRegistration.deliver(HandlerRegistration.java:228)) [vert.x-eventloop-thread-4] []
java.lang.NullPointerException: null
at com.vaadin.server.AbstractExtension.extend(AbstractExtension.java:77) ~[vaadin-server-8.4.4.jar:8.4.4]
at com.vaadin.ui.Notification.show(Notification.java:502) ~[vaadin-server-8.4.4.jar:8.4.4]
at de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda[=18=](AgreementsViewLogic.java:39) ~[classes/:?]
at io.vertx.core.impl.FutureImpl.tryFail(FutureImpl.java:165) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.impl.FutureImpl.fail(FutureImpl.java:97) ~[vertx-core-3.5.1.jar:3.5.1]
at de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda(AgreementsViewLogic.java:62) ~[classes/:?]
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$convertHandler(EventBusImpl.java:349) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.HandlerRegistration.deliver(HandlerRegistration.java:223) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.HandlerRegistration.handle(HandlerRegistration.java:200) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$deliverToHandler(EventBusImpl.java:533) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.impl.ContextImpl.lambda$wrapTask(ContextImpl.java:339) ~[vertx-core-3.5.1.jar:3.5.1]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463) [netty-transport-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:886) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_171]
[ERROR] 2018-08-07 09:42:54,383: Unhandled exception ( io.vertx.core.impl.ContextImpl.lambda$wrapTask(ContextImpl.java:345)) [vert.x-eventloop-thread-4] []
java.lang.NullPointerException: null
at com.vaadin.server.AbstractExtension.extend(AbstractExtension.java:77) ~[vaadin-server-8.4.4.jar:8.4.4]
at com.vaadin.ui.Notification.show(Notification.java:502) ~[vaadin-server-8.4.4.jar:8.4.4]
at de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda[=18=](AgreementsViewLogic.java:39) ~[classes/:?]
at io.vertx.core.impl.FutureImpl.tryFail(FutureImpl.java:165) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.impl.FutureImpl.fail(FutureImpl.java:97) ~[vertx-core-3.5.1.jar:3.5.1]
at de.bfft.licencemgmt.client.viewslogic.agreements.AgreementsViewLogic.lambda(AgreementsViewLogic.java:62) ~[classes/:?]
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$convertHandler(EventBusImpl.java:349) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.HandlerRegistration.deliver(HandlerRegistration.java:223) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.HandlerRegistration.handle(HandlerRegistration.java:200) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$deliverToHandler(EventBusImpl.java:533) ~[vertx-core-3.5.1.jar:3.5.1]
at io.vertx.core.impl.ContextImpl.lambda$wrapTask(ContextImpl.java:339) ~[vertx-core-3.5.1.jar:3.5.1]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463) [netty-transport-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:886) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.19.Final.jar:4.1.19.Final]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_171]
而在UserVerticle.javaclass中导致异常的代码,堆栈跟踪中的第998行对应于下面的第三行"log.error(arContracts.cause())":
private void fetchContracts(final Message<Void> msg) {
contractDao.findAll().setHandler(arContracts -> {
if (arContracts.failed()) {
log.error(arContracts.cause());
msg.fail(500, arContracts.cause().getMessage());
return;
}
final List<Contract> contracts = arContracts.result();
log.debug("Found {} contracts", contracts.size());
final JsonArray jsonArray = new JsonArray(
contracts.stream().map(contract -> contract.toJson()).collect(Collectors.toList()));
msg.reply(jsonArray);
});
}
问题出在json中的十进制转换。 Json 自动将十进制数转换为字符串,但它需要一个十进制数,这在某种程度上引发了异常
事实证明,还有一个额外的 CustomVertxGenerator.java class 扩展了 ClassicAsyncVertxGenerator for vert.x-jooq,它有一个方法来处理额外的类型 from/into a String during JSON-转换。这对我来说是新的。
在 class 的方法中修复了 postgresql 数据库中数字类型的转换后,问题就解决了。