H2 JdbcSQLException:“找不到表”,带有驼峰表和实体名称
Posted
技术标签:
【中文标题】H2 JdbcSQLException:“找不到表”,带有驼峰表和实体名称【英文标题】:H2 JdbcSQLException: "Table not found" with camelcase table & entity name 【发布时间】:2016-02-04 19:35:21 【问题描述】:使用 Spring Boot、Spring Data JPA 和 H2 内存数据库(如果有影响,则使用 PostgreSQL 模式)。
我有一个名为ContentBlock
的表和实体类,但是当我执行findAll()
或findOne()
时,H2 抱怨缺少CONTENT_BLOCK
表:
org.h2.jdbc.JdbcSQLException: Table "CONTENT_BLOCK" not found
我不确定大写/驼峰式是否有区别,但CONTENT_BLOCK
中的下划线来自哪里?
在我的架构定义中:
CREATE TABLE ContentBlock (
id BIGSERIAL PRIMARY KEY,
content TEXT
-- etc
);
而在实体类中:
@Entity
@Table(name = "ContentBlock")
public class ContentBlock
// ...
(当然我第一次尝试不使用@Table
注释,因为类名与表名完全匹配。)
对于我的其他表/实体,名称如Asset
,没有问题,我不需要在Java端显式指定表名:
@Entity
public class Asset
// ...
在我的设置中,H2 数据源是这样明确定义的:
@Bean
public DataSource devDataSource()
return new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(EmbeddedDatabaseType.H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScripts("database/init.sql", "database/schema.sql", "database/test_data.sql")
.build();
(init.sql
的内容为SET MODE PostgreSQL;
)
作为解决方法,我刚刚将schema.sql
中的ContentBlock
表重命名为Block
,在Java 类中使用@Table(name = "Block")
,我仍然称之为ContentBlock
。
但这很奇怪,你肯定可以以某种方式将带有驼峰名称的表映射到实体吗?
【问题讨论】:
实际上还有其他列,例如对另一个表的外键引用,但这并不相关;我可以通过像上面这样简单的设置来重现这个问题。 也许在名字周围加上(单)引号?也许值得一试。一些 RDBMS 使用引号作为允许区分大小写的一种方式 @NeilStockton:嗯,在 CREATE TABLE 语句中使用单引号会产生语法错误,但使用双引号我实际上得到了Table "CONTENTBLOCK" not found
(没有下划线!),所以你可能会在这里找到一些东西。
我认为这可以使用双引号和 DATABASE_TO_UPPER=false
来解决。但我不确定如何指定,因为我没有在应用程序的任何地方明确使用 H2 连接 URL...
【参考方案1】:
默认情况下Spring Boot
使用SpringNamingStrategy。它从 Hibernate 4 扩展了 org.hibernate.cfg.ImprovedNamingStrategy
。ImprovedNamingStrategy
在表名中生成下划线。
要将带有驼峰式名称的表映射到实体,您可以使用org.hibernate.cfg.EJB3NamingStrategy
或实现您自己的。
使用属性设置命名策略的示例
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
【讨论】:
以上是关于H2 JdbcSQLException:“找不到表”,带有驼峰表和实体名称的主要内容,如果未能解决你的问题,请参考以下文章
获取“org.h2.jdbc.JdbcSQLException:找不到表“BOOK_PUBLISHERS”;SQL 语句:”
org.h2.jdbc.JdbcSQLException:找不到表“ALL_SEQUENCES”
使用 h2 进行 Spring Junit 测试 - 找不到表