问题
jdbc进行数据查询,控制台终端报错
java.lang.RuntimeException: java.sql.SQLException: Cannot create com.iflytek.bms.domain.ChatObject: com.iflytek.bms.domain.ChatObject Query: SELECT * FROM chatobject where myId = ? Parameters: [2]
详细错误
笔者查询语句
@Override
public List<ChatObject> selectChatObjectByMyId(Integer myId) {
String sql = "SELECT * FROM chatobject where myId = ?";
try {
return runner.query(sql, new BeanListHandler<>(ChatObject.class), myId);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
笔者查询对象
package com.iflytek.bms.domain;
import lombok.Data;
import java.sql.Timestamp;
@Data
public class ChatObject {
private Integer id;
private Integer myId;
private Integer otherId;
private String otherName;
private String headSculpture;
private Integer state;
private Timestamp time;
public ChatObject(Integer id, Integer myId, Integer otherId, String otherName, String headSculpture, Integer state, Timestamp time) {
this.id = id;
this.myId = myId;
this.otherId = otherId;
this.otherName = otherName;
this.headSculpture = headSculpture;
this.state = state;
this.time = time;
}
}
笔者数据库设计
控制台终端详细报错
29-May-2023 11:18:00.694 ���� [http-nio-8080-exec-8] org.apache.catalina.core.StandardWrapperValve.invoke ��·��Ϊ[/bms]���������У�servlet[ChatObjectListServlet]��Servlet.service()�����쳣
java.lang.RuntimeException: java.sql.SQLException: Cannot create com.iflytek.bms.domain.ChatObject: com.iflytek.bms.domain.ChatObject Query: SELECT * FROM chatobject where myId = ? Parameters: [2]
at com.iflytek.bms.dao.impl.ChatObjectDaoImpl.selectChatObjectByMyId(ChatObjectDaoImpl.java:91)
at com.iflytek.bms.service.impl.ChatObjectServiceImpl.selectChatObjectByMyId(ChatObjectServiceImpl.java:26)
at com.iflytek.bms.web.ChatObjectListServlet.doGet(ChatObjectListServlet.java:53)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:670)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.iflytek.bms.web.filter.LoginFilter.doFilter(LoginFilter.java:33)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.iflytek.bms.web.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:26)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.sql.SQLException: Cannot create com.iflytek.bms.domain.ChatObject: com.iflytek.bms.domain.ChatObject Query: SELECT * FROM chatobject where myId = ? Parameters: [2]
at org.apache.commons.dbutils.AbstractQueryRunner.rethrow(AbstractQueryRunner.java:527)
at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:391)
at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:329)
at com.iflytek.bms.dao.impl.ChatObjectDaoImpl.selectChatObjectByMyId(ChatObjectDaoImpl.java:89)
... 32 more
解决方案1
删除类中自定义构造函数
package com.iflytek.bms.domain;
import lombok.Data;
import java.sql.Timestamp;
@Data
public class ChatObject {
private Integer id;
private Integer myId;
private Integer otherId;
private String otherName;
private String headSculpture;
private Integer state;
private Timestamp time;
}
解决方案2
自定义无参构造函数
package com.iflytek.bms.domain;
import lombok.Data;
import java.sql.Timestamp;
@Data
public class ChatObject {
private Integer id;
private Integer myId;
private Integer otherId;
private String otherName;
private String headSculpture;
private Integer state;
private Timestamp time;
public ChatObject() {
}
}
解决原因
由于笔者引入了lombok的Data注解,@Data 是 Lombok 提供的一个注解,它可以自动为类生成一些通用的方法,帮助简化代码。
@Data 注解主要有以下作用:
1、自动生成 Getter 和 Setter 方法:@Data 注解会为类中的每个非静态字段生成对应的 Getter 和 Setter 方法,使得属性的访问和修改更加便捷。
2、自动生成 toString() 方法:@Data 注解会自动生成一个 toString() 方法,用于将对象转换为字符串表示形式。生成的 toString() 方法将按照属性的顺序生成类似于 “ClassName(fieldName1=value1, fieldName2=value2, …)” 的字符串。
3、自动生成 equals() 和 hashCode() 方法:@Data 注解会自动生成 equals() 和 hashCode() 方法,用于对象的相等性比较和哈希码计算。生成的方法将基于类中的所有非静态字段进行比较和计算。
4、自动生成全参和无参的构造方法:@Data 注解会自动生成包含所有非静态字段的全参构造方法和无参构造方法,简化对象的创建和初始化过程。
5、自动生成 @RequiredArgsConstructor 注解:当类中存在 final 或 @NonNull 注解修饰的字段时,@Data 注解会自动为这些字段生成一个带有 @RequiredArgsConstructor 注解的构造方法。
然而,当Java实体类中定义了自定义构造函数时,它将覆盖Lombok的@Data注解生成的默认构造函数。这是由于自定义构造函数提供了更具体的初始化逻辑,因此Lombok不会生成默认构造函数。
但是在JDBC执行SQL语句生成查询对象时,由于JDBC生成查询对象使用无参构造函数,之后通过调用实体对象的set方式向所生成的查询对象对应字段赋值,笔者自定义部分参数构造函数后覆盖Lombok的@Data注解生成的默认构造函数,同时又没有自定义无参构造函数。这导致实体类此时无无参构造函数,故会报错
java.lang.RuntimeException: java.sql.SQLException: Cannot create com.iflytek.bms.domain.ChatObject: com.iflytek.bms.domain.ChatObject Query: SELECT * FROM chatobject where myId = ? Parameters: [2]
解决方案一去除自定义部分参数构造函数,使@Data 注解自动生成的无参构造函数生效
解决方案一自定义无参数构造函数,此时实体类此时含有无参构造函数,JDBC生成查询对象便可正常调用无参构造函数
总结
java.lang.RuntimeException: java.sql.SQLException: Cannot create com.iflytek.bms.domain.ChatObject: com.iflytek.bms.domain.ChatObject Query: SELECT * FROM chatobject where myId = ? Parameters: [2]
报错信息其实具有一定的误导性,笔者之所以自定义参数,误以为由于笔者实体类与数据库表中字段由于无法完成一对一映射所导致的, 这里的Parameters: [2]是指两个参数无法映射,但当笔者将发送的myId参数改为1,报错变为
java.lang.RuntimeException: java.sql.SQLException: Cannot create com.iflytek.bms.domain.ChatObject: com.iflytek.bms.domain.ChatObject Query: SELECT * FROM chatobject where myId = ? Parameters: [1]
很显然,这不是参数映射的问题
在笔者看来,若是报错信息改为无法找到无参构造函数,似乎对于开发者更友好
参考文献
解决原因参考chatgpt
原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈