如何解决由于缺少列名而出现JDBI错误
我正在尝试使用jdbi将用户添加到MysqL数据库,但是当我尝试添加用户时,出现错误消息,提示我缺少列username
CREATE TABLE users
(
id int NOT NULL AUTO_INCREMENT,username varchar(100) NOT NULL,password text NOT NULL,email varchar(150) NOT NULL,salt text NOT NULL,is_admin boolean DEFAULT FALSE,is_active boolean DEFAULT TRUE,PRIMARY KEY (id),UNIQUE KEY username (username),UNIQUE KEY email (email)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
用户类别
public class UserEntity implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
@NotEmpty(message = "The username must be set")
@Size(min = 3,max = 100,message = "The username must be between 3 and 100 characters")
private String username;
@NotEmpty(message = "The password must be set")
@Size(min = 8,message = "The password must be at least 8 characters long")
private String password;
@NotEmpty(message = "email must be set")
@Email(message = "The email must be in the form user@domain.com")
private String email;
private String salt;
private boolean isAdmin;
private boolean isActive;
public UserEntity(String username,String password,String email,boolean isAdmin,boolean isActive) {
this(username,password,email,null,isAdmin,isActive);
}
public UserEntity(Integer id,String username,boolean isActive) {
}
@JsonCreator
public UserEntity(
@JsonProperty("username") String username,@JsonProperty("password") String password,@JsonProperty("email") String email,String salt,@JsonProperty("isAdmin") boolean isAdmin,@JsonProperty("isActive") boolean isActive) {
this.username = username;
this.password = password;
this.email = email;
this.salt = salt;
this.isAdmin = isAdmin;
this.isActive = isActive;
}
@JsonProperty
@NotEmpty
public Integer getId() {
return id;
}
@JsonProperty
@NotEmpty
public String getUsername() {
return username;
}
@JsonProperty
@NotEmpty
public String getpassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@JsonProperty
@NotEmpty
public String getEmail() {
return email;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
@JsonProperty
public boolean isAdmin() {
return isAdmin;
}
@JsonProperty
public boolean isActive() {
return isActive;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity userEntity = (UserEntity) o;
return getId() == userEntity.getId() &&
isAdmin() == userEntity.isAdmin() &&
isActive() == userEntity.isActive() &&
Objects.equals(getUsername(),userEntity.getUsername()) &&
Objects.equals(getpassword(),userEntity.getpassword()) &&
Objects.equals(getSalt(),userEntity.getSalt()) &&
Objects.equals(getEmail(),userEntity.getEmail());
}
@Override
public int hashCode() {
return Objects.hash(getId(),getUsername(),getpassword(),getEmail(),getSalt(),isAdmin(),isActive());
}
@Override
public String toString() {
return "UserEntity{" +
"id=" + id +
",username='" + username + '\'' +
",password='" + password + '\'' +
",email='" + email + '\'' +
",isAdmin=" + isAdmin +
",isActive=" + isActive +
'}';
}
@RegisterRowMapper(MapperImpl.class)
@RegisterBeanMapper(MapperImpl.class)
public interface DAO {
@sqlUpdate("INSERT INTO users (username,salt,is_admin,is_active) " +
"VALUES (:username,:password,:email,:salt,false,true)")
@GetGeneratedKeys
UserEntity addUser(@Bind("username") String username,@Bind("password") String password,@Bind("email") String email,@Bind("salt") String salt);
@sqlUpdate("INSERT INTO users (username,true,true)")
@GetGeneratedKeys
UserEntity addAdminUser(@Bind("username") String username,@Bind("salt") String salt);
@sqlQuery("SELECT username,is_active " +
"FROM users")
@GetGeneratedKeys
List<UserEntity> getAllUsers();
@sqlQuery("SELECT username,is_active " +
"FROM users " +
"WHERE is_admin = false")
@GetGeneratedKeys
List<UserEntity> getAllRegularUsers();
@sqlQuery("SELECT username,is_active " +
"FROM users " +
"WHERE is_admin = true")
@GetGeneratedKeys
List<UserEntity> getAllAdminUsers();
@sqlQuery("SELECT username,is_active " +
"FROM users " +
"WHERE email = :email")
@GetGeneratedKeys
UserEntity getUserByEmail(@Bind("email") String email);
@sqlUpdate("UPDATE users " +
"SET is_admin = false " +
"WHERE email = :email")
@GetGeneratedKeys
UserEntity revokeAdminRights(@Bind("email") String email);
@sqlUpdate("UPDATE users " +
"SET is_admin = true " +
"WHERE email = :email")
@GetGeneratedKeys
UserEntity promotetoAdmin(@Bind("email") String email);
@sqlUpdate("UPDATE users " +
"SET is_active = false " +
"WHERE email = :email")
@GetGeneratedKeys
UserEntity deactivateUser(@Bind("email") String email);
@sqlUpdate("UPDATE users " +
"SET is_active = true " +
"WHERE email = :email")
@GetGeneratedKeys
UserEntity reactivateUser(@Bind("email") String email);
@sqlUpdate("UPDATE users " +
"SET password = password,salt = :salt " +
"WHERE email = :email")
@GetGeneratedKeys
UserEntity updateUserPassword(@Bind("password") String password,@Bind("salt") String salt);
}
public static class MapperImpl implements RowMapper<UserEntity> {
@Override
public UserEntity map(ResultSet rs,StatementContext ctx) throws sqlException {
return new UserEntity(
rs.getString("username"),rs.getString("password"),rs.getString("email"),rs.getString("salt"),rs.getBoolean("is_admin"),rs.getBoolean("is_active")
);
}
}
}
当我在addUser()
界面中调用DAO
方法时,出现以下错误;
org.jboss.resteasy.spi.UnhandledException: org.jdbi.v3.core.result.ResultSetException: Error thrown mapping result set into return type [statement:"INSERT INTO users (username,is_active) VALUES (:username,true)",arguments:{positional:{0:danny,1:ce672ce95ca0d5792b2d24fa9c58c078a78545d2bfc3354d23c0d5066c1d7aac49fa308a7ffc9b8bf449e9b62e732e4ea742026086ab5e252a0ced2cf59edea8,2:doldy101@gmail.com,3:1b922bc3dadc6a5ecc5e46ba241c1223},named:{password:ce672ce95ca0d5792b2d24fa9c58c078a78545d2bfc3354d23c0d5066c1d7aac49fa308a7ffc9b8bf449e9b62e732e4ea742026086ab5e252a0ced2cf59edea8,salt:1b922bc3dadc6a5ecc5e46ba241c1223,email:doldy101@gmail.com,username:danny},finder:[]}]
at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:106)
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)
at org.jboss.resteasy.core.Synchronousdispatcher.writeException(Synchronousdispatcher.java:216)
at org.jboss.resteasy.core.Synchronousdispatcher.invoke(Synchronousdispatcher.java:515)
at org.jboss.resteasy.core.Synchronousdispatcher.lambda$invoke$4(Synchronousdispatcher.java:259)
at org.jboss.resteasy.core.Synchronousdispatcher.lambda$preprocess$0(Synchronousdispatcher.java:160)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.Synchronousdispatcher.preprocess(Synchronousdispatcher.java:163)
at org.jboss.resteasy.core.Synchronousdispatcher.invoke(Synchronousdispatcher.java:245)
at io.quarkus.resteasy.runtime.standalone.Requestdispatcher.service(Requestdispatcher.java:73)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:132)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:37)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:94)
at io.quarkus.runtime.CleanableExecutor$CleaningRunnable.run(CleanableExecutor.java:231)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossthread.run(JBossthread.java:479)
Caused by: org.jdbi.v3.core.result.ResultSetException: Error thrown mapping result set into return type [statement:"INSERT INTO users (username,finder:[]}]
at org.jdbi.v3.core.result.ResultSetResultIterator.next(ResultSetResultIterator.java:85)
at org.jdbi.v3.core.result.ResultIterable.findFirst(ResultIterable.java:204)
at org.jdbi.v3.sqlobject.statement.internal.ResultReturner$CollectedResultReturner.mappedResult(ResultReturner.java:269)
at org.jdbi.v3.sqlobject.statement.internal.sqlUpdateHandler.lambda$new$0(sqlUpdateHandler.java:60)
at org.jdbi.v3.sqlobject.statement.internal.sqlUpdateHandler.lambda$configureReturner$3(sqlUpdateHandler.java:78)
at org.jdbi.v3.sqlobject.statement.internal.CustomizingStatementHandler.invoke(CustomizingStatementHandler.java:153)
at org.jdbi.v3.sqlobject.statement.internal.sqlUpdateHandler.invoke(sqlUpdateHandler.java:31)
at org.jdbi.v3.sqlobject.internal.sqlObjectinitData$1.lambda$invoke$0(sqlObjectinitData.java:125)
at org.jdbi.v3.core.internal.Invocations.invokeWith(Invocations.java:44)
at org.jdbi.v3.core.ConstantHandlesupplier.lambda$invokeInContext$0(ConstantHandlesupplier.java:56)
at org.jdbi.v3.core.internal.Invocations.invokeWith(Invocations.java:44)
at org.jdbi.v3.core.ConstantHandlesupplier.invokeInContext(ConstantHandlesupplier.java:52)
at org.jdbi.v3.sqlobject.internal.sqlObjectinitData$1.call(sqlObjectinitData.java:131)
at org.jdbi.v3.sqlobject.internal.sqlObjectinitData$1.invoke(sqlObjectinitData.java:125)
at org.jdbi.v3.sqlobject.sqlObjectFactory.lambda$attach$2(sqlObjectFactory.java:110)
at com.sun.proxy.$Proxy78.addUser(UnkNown Source)
at io.shopik.services.UserService.lambda$addRegularUser$0(UserService.java:29)
at org.jdbi.v3.core.transaction.LocalTransactionHandler.inTransaction(LocalTransactionHandler.java:134)
at org.jdbi.v3.core.Handle.inTransaction(Handle.java:422)
at org.jdbi.v3.core.jdbi.lambda$inTransaction$4(jdbi.java:375)
at org.jdbi.v3.core.jdbi.withHandle(jdbi.java:341)
at org.jdbi.v3.core.jdbi.inTransaction(jdbi.java:375)
at io.shopik.services.UserService.addRegularUser(UserService.java:25)
at io.shopik.services.UserService_ClientProxy.addRegularUser(UserService_ClientProxy.zig:216)
at io.shopik.resources.UserResource.createNewRegularUser(UserResource.java:49)
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.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:638)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:504)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:454)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:456)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:417)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:391)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)
at org.jboss.resteasy.core.Synchronousdispatcher.invoke(Synchronousdispatcher.java:488)
... 20 more
Caused by: java.sql.sqlException: Column 'username' not found.
at com.MysqL.cj.jdbc.exceptions.sqlError.createsqlException(sqlError.java:129)
at com.MysqL.cj.jdbc.exceptions.sqlError.createsqlException(sqlError.java:97)
at com.MysqL.cj.jdbc.exceptions.sqlError.createsqlException(sqlError.java:89)
at com.MysqL.cj.jdbc.exceptions.sqlError.createsqlException(sqlError.java:63)
at com.MysqL.cj.jdbc.result.ResultSetImpl.findColumn(ResultSetImpl.java:556)
at com.MysqL.cj.jdbc.result.ResultSetImpl.getString(ResultSetImpl.java:863)
at io.agroal.pool.wrapper.ResultSetWrapper.getString(ResultSetWrapper.java:267)
at io.shopik.entities.UserEntity$MapperImpl.map(UserEntity.java:218)
at io.shopik.entities.UserEntity$MapperImpl.map(UserEntity.java:214)
at org.jdbi.v3.core.result.ResultSetResultIterator.next(ResultSetResultIterator.java:83)
... 59 more
我不确定我在做什么错。有什么想法吗?
修改 遵循@nbk的建议,我放下桌子并通过Workbench进行读取,但是这次我添加了反引号。这没什么!
CREATE TABLE users
(
`id` int NOT NULL AUTO_INCREMENT,`username` varchar(100) NOT NULL,`password` text NOT NULL,`email` varchar(150) NOT NULL,`salt` text NOT NULL,`is_admin` boolean DEFAULT FALSE,`is_active` boolean DEFAULT TRUE,PRIMARY KEY (`id`),UNIQUE KEY `username` (`username`),UNIQUE KEY `email` (`email`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
编辑#2
UserResource
@Path("/user")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class UserResource {
@Inject
UserService userService;
@POST
public Response createNewRegularUser(@Valid UserEntity userEntity) {
UserEntity user = userService.addRegularUser(userEntity);
if (user != null) {
return Response.ok(user).build();
}
return Response.noContent().build();
}
}
UserService
@ApplicationScoped
public class UserService {
@Inject
jdbiProvider dbi;
public UserEntity addRegularUser(UserEntity user) {
return dbi.get().inTransaction(handle -> {
hashPassword(user);
LOGGER.info("Hashed password for user {} and adding as user",user.getEmail());
return handle.attach(UserEntity.DAO.class)
.addUser(user.getUsername(),user.getpassword(),user.getEmail(),user.getSalt());
});
}
}
解决方法
我决定将数据库从MySQL更改为PostgreSQL,因为MySQL的docker容器启动时间太长。这样,我更新了我的应用程序文件pom.xml,然后更新了sql文件以修复语法。当我运行应用程序并决定添加一个用户(不更改任何代码)并将该用户添加到数据库中时,我感到很幸运,我得到了邮差的回复
在我看来这是一个MySQL问题,当我换成Postgres时,这个问题就消失了
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。