如何修复“java.sql.SQLException:找不到列 'id'。” Spring Boot 中的错误

Posted

技术标签:

【中文标题】如何修复“java.sql.SQLException:找不到列 \'id\'。” Spring Boot 中的错误【英文标题】:How to fix "java.sql.SQLException: Column 'id' not found." error in Spring Boot如何修复“java.sql.SQLException:找不到列 'id'。” Spring Boot 中的错误 【发布时间】:2019-12-07 08:43:47 【问题描述】:

有 2 个实体:Deck 和 Card。每副牌包含 100 张可能的卡片中的 8 张。由于每个牌组包含不止一张牌,而且牌组也可以是许多不同牌组的一部分,因此我通过创建一个名为 deck_cards 的新表来加入它们。

@Data
@Entity
@Table(name = "cards")
public class Card 
    @Id
    private Integer id;

    @NotBlank
    private String icon;

    @NotBlank
    private String name;

    @ManyToMany(fetch = FetchType.LAZY,
                cascade = 
                    CascadeType.PERSIST,
                    CascadeType.MERGE
                ,
                mappedBy = "cards")
    private Set<Deck> decks;
// setters and getters


@Data
@Entity
@Table(name="decks")
public class Deck 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToMany(fetch = FetchType.LAZY,
                cascade = 
                    CascadeType.PERSIST,
                    CascadeType.MERGE
                )
    @JoinTable(name = "deck_cards",
            joinColumns =  @JoinColumn(name = "deck_id", 
referencedColumnName = "id"),
            inverseJoinColumns =  @JoinColumn(name = "card_id", 
referencedColumnName = "id"))
    private Set<Card> cards = new HashSet<>();
// setters and getters


@Repository
@Transactional(readOnly = true)
public class DeckRepositoryImpl implements DeckRepositoryCustom 

    @PersistenceContext
    EntityManager entityManager;

    @Override
    public Deck getDeckContaining(List<String> cardIds) 
        String queryStr =
                "select deck_id\n" +
                "from deck_cards\n" +
                // Hard-coding card_ids of interest for now to 
                // see if the query itself works
                "where card_id in (1, 2, 3, 4, 5, 6, 7, 8)\n" +
                "group by deck_id\n" +
                "having count(*) = 8";
        Query query = entityManager.createNativeQuery(queryStr, 
Deck.class);
    return (Deck) query.getSingleResult();

我有一个名为 getDeckContaining() 的自定义方法,它最初设计用于接收 List cardIds 并查看是否有包含存储在列表中的 id 的卡片组。现在,我硬编码了要在查询字符串中查找的卡片 ID。即使这样,当我调用这样的方法时:

    List<String> teamCardIdsInString = new ArrayList<>();
    //....
    Deck deckOfInterest = 
    deckRepository.getDeckContaining(teamCardIdsInString);

我收到以下错误消息:

2019-07-29 19:00:06.663  WARN 3409 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: S0022
2019-07-29 19:00:06.664 ERROR 3409 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : Column 'id' not found.
2019-07-29 19:00:06.690 ERROR 3409 --- [nio-8080-exec-1] 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 deck_id
from deck_cards
where card_id in (26000060, 28000017, 26000044, 26000039, 26000027, 28000015, 26000033, 28000000)
group by deck_id
having count(*) = 8]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query] with root cause

java.sql.SQLException: Column 'id' not found.
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.16.jar:8.0.16]
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.16.jar:8.0.16]
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89) ~[mysql-connector-java-8.0.16.jar:8.0.16]
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63) ~[mysql-connector-java-8.0.16.jar:8.0.16]
        at com.mysql.cj.jdbc.result.ResultSetImpl.findColumn(ResultSetImpl.java:561) ~[mysql-connector-java-8.0.16.jar:8.0.16]
        at com.mysql.cj.jdbc.result.ResultSetImpl.getInt(ResultSetImpl.java:825) ~[mysql-connector-java-8.0.16.jar:8.0.16]
        at com.zaxxer.hikari.pool.HikariProxyResultSet.getInt(HikariProxyResultSet.java) ~[HikariCP-3.2.0.jar:na]
        at org.hibernate.type.descriptor.sql.IntegerTypeDescriptor$2.doExtract(IntegerTypeDescriptor.java:62) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
        at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
        at 

我很困惑,因为我认为我使用了实体中定义的字段名称。有什么我可能错过的吗?

【问题讨论】:

所以你的数据库中有“甲板”表?您没有在 "Deck" 类之前指定任何 "@Table" 注释,因此 JPA 将默认查找 "Deck" 表 糟糕,我忘记在复制粘贴代码时添加指定表名的部分。它以@Data@Entity@Table(name="decks") 的形式存在,但仍然无法正常工作 【参考方案1】:

java.sql.SQLException: 找不到列 'id'。 问题在于列的名称。 referencedColumnName = "id" 是这里可能的嫌疑人(下)

可能的解决方案:

删除referencedColumnName = "id" 由于您没有按照数据库方案发布名称(也没有@Column),请确保数据库中的 id 字段存在

【讨论】:

两个实体的 id 列名称相同有什么问题? 您好@mangusta,在我们的上一个项目中,有人创建了具有相同名称的列,并且对于关系映射,我们必须准确地指出我们所指的实体。在我看来,最好有一个带有关联实体的名称,例如deckId,不是吗? 没什么区别,joinColumns和inverseJoinColumns指的是不同的表,所以jpa知道“referencedColumnName”属于哪个表 我在这里看到的唯一可能原因是“卡片”或“甲板”中的任何一个都没有 id 列(可能两者都有) 可能是这种情况或db中的名称可能不同

以上是关于如何修复“java.sql.SQLException:找不到列 'id'。” Spring Boot 中的错误的主要内容,如果未能解决你的问题,请参考以下文章

ORA-00904: "pass": 无效的标识符

如何修复 npm 审计修复问题?

如何修复drv?

如何修复漏洞

如何修复WMI

PHP网站漏洞怎么修复 如何修补网站程序代码漏洞