简体   繁体   中英

java.sql.SQLException: Column 'serialnumber' not found. (spring boot)

I am writing to-do list web app with spring boot. I Have 2 entities: User (fields: userid (ID), username, password Item (fields: serialnumber (ID), task, userid. I want to allow each user to see only his tasks. So I try to pull all the tasks from "task" table. When I try to retrieve information by a custom query, (I think) hibernate fails to read the table. But when I use a built-in method like findAll() from the Repository interface it's works.

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Item {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer serialnumber;
    private int userid;
    private String task;

    public Item() {

    }

    public Item(int userid, String task) {
        this.userid = userid;
        this.task = task;
    }

    public Integer getSerialnumber() {
        return serialnumber;
    }

    public void setSerialnumber(Integer serialnumber) {
        this.serialnumber = serialnumber;
    }

    public int getUserid() {
        return userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

    public String getTask() {
        return task;
    }

    public void setTask(String task) {
        this.task = task;
    }

    @Override
    public String toString() {
        return "Item{" +
                "serialnumber=" + serialnumber +
                ", userid=" + userid +
                ", task='" + task + '\'' +
                '}';
    }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;

@Controller
public class MainController {


    @Autowired
    private ItemRepository itemRepository;

.....

@PostMapping("/addItem")
    public String addItem(@RequestParam String task,
                          @CookieValue(name = "id") String id,
                          Model model) {

        Item item = new Item(Integer.valueOf(id), task);
        itemRepository.save(item);
        print(item.toString());
        model.addAttribute("items", itemRepository.findItemsByUserId(Integer.valueOf(id)));
        return "list";
    } 
......
}
import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface ItemRepository extends CrudRepository<Item, Integer> {

    @Query(value = "SELECT task FROM item WHERE userid = ?1", nativeQuery = true)
    List<Item> findItemsByUserId(Integer userid);

}
Hibernate: SELECT task FROM item WHERE userid = ?
2022-04-02 23:23:45.733  WARN 36504 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: S0022
2022-04-02 23:23:45.733 ERROR 36504 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : Column 'serialnumber' not found.
2022-04-02 23:23:45.743 ERROR 36504 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query; SQL [SELECT task FROM item WHERE userid = ?]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query] with root cause

java.sql.SQLException: Column 'serialnumber' not found.
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.28.jar:8.0.28]

The problem could probably be that your query specifies the column task in the select clause, but you're expecting a List<Item> as return type in the findItemsByUserId method.

If you want the entire Item to be returned, then you should change your query to "SELECT * FROM item WHERE userid =?1" in order to select all columns.

But, if what you want is the field task only, then you must change the method return type because you want a projection (specific columns selection). That could be done by defining an interface like:

public interface TaskDto {
    String getTask();
}

Then you have to choose between:

@Query(value = "SELECT task FROM item WHERE userid = ?1", nativeQuery = true)
List<TaskDto> findItemsByUserId(Integer userid);

and

@Query(value = "SELECT * FROM item WHERE userid = ?1", nativeQuery = true)
List<Item> findItemsByUserId(Integer userid);
@Query(value = "SELECT task FROM item WHERE userid = ?1", nativeQuery = true)
List<Item> findItemsByUserId(Integer userid);

Clearly your query is returning a List of String values and you are trying to cast them to List of your Item entity.

If you want to fetch your result as List of item, use

@Query(value = "SELECT * FROM item WHERE userid = ?1", nativeQuery = true)
List<Item> findItemsByUserId(Integer userid);

or if you want just the String list of tasks, use

@Query(value = "SELECT task FROM item WHERE userid = ?1", nativeQuery = true)
List<String> findItemsByUserId(Integer userid);

Change the caller methods accordingly. As per your error "serialnumber not found", while JPA/Hibernate use reflection API for mapping individual columns from table to their appropriate fields in entity. Since you are specifically fetching "task", all the other columns are missing. Hence "serialnumber not found".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM