获取缺少列名的jdbi错误

64jmpszr  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(604)

我正在尝试使用jdbi向mysql数据库添加用户,但是当我尝试添加用户时,我得到一个错误,说我缺少一列 username sql语句

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, String password, String email, boolean isAdmin, 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, password, email, 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, password, email, salt, is_admin, is_active) " +
                "VALUES (:username, :password, :email, :salt, true, true)")
        @GetGeneratedKeys
        UserEntity addAdminUser(@Bind("username") String username,
                                @Bind("password") String password,
                                @Bind("email") String email,
                                @Bind("salt") String salt);

        @SqlQuery("SELECT username, password, email, is_admin, is_active " +
                "FROM users")
        @GetGeneratedKeys
        List<UserEntity> getAllUsers();

        @SqlQuery("SELECT username, password, email, is_admin, is_active " +
                "FROM users " +
                "WHERE is_admin = false")
        @GetGeneratedKeys
        List<UserEntity> getAllRegularUsers();

        @SqlQuery("SELECT username, password, email, is_admin, is_active " +
                "FROM users " +
                "WHERE is_admin = true")
        @GetGeneratedKeys
        List<UserEntity> getAllAdminUsers();

        @SqlQuery("SELECT username, password, email, is_admin, 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("email") String email,
                                      @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, password, email, salt, is_admin, is_active) VALUES (:username, :password, :email, :salt, false, 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, password, email, salt, is_admin, is_active) VALUES (:username, :password, :email, :salt, false, 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.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

是说我没有专栏 username 但我可以证实那一列在那里;

我不知道我做错了什么。有什么想法吗?
按照@nbk的建议编辑我删除了表并通过workbench读取,但这次我包含了backticks。这没什么区别!
sql语句

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
包括端点和服务方法
用户资源

@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();
    }

}

用户服务

@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());
        });
    }

}

注:只包括必要的方法,以免问题过重

bgtovc5b

bgtovc5b1#

我决定把数据库从mysql改成postgresql,因为mysql的docker容器太长了。我更新了我的应用程序文件pom.xml和sql文件来修复语法。当我让应用程序运行并决定添加一个用户(不更改任何代码)并且该用户被添加到数据库中时,我运气不好,得到了postman的响应
在我看来,这是一个mysql的问题,因为当我改为postgres,这个问题消失了

相关问题