Spring 使用 WebFlux 启动时 H2 和 R2DBC 未找到列错误
Column Not Found Error with H2 and R2DBC in Spring Boot with WebFlux
我使用 WebFlux 反应模块、H2 内存数据库和 R2DBC 反应驱动程序创建了 Java Spring 引导服务。这在端口 8081 上构建并运行良好。
我在 main/resources 下添加了一个 schema.sql 文件,其中包含以下内容:
CREATE TABLE contentitem ( contentItemId INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, localizedName VARCHAR(100) NOT NULL);
我在同一目录中使用 data.sql 文件填充 table:
INSERT INTO contentitem (contentItemId, localizedName) VALUES (0, 'Zero');
INSERT INTO contentitem (contentItemId, localizedName) VALUES (1, 'One');
INSERT INTO contentitem (contentItemId, localizedName) VALUES (2, 'Two');
我的 ContentItem 模型是:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table("contentitem")
public class ContentItem {
@Id
private Integer contentItemId;
private String localizedName;
我的 ContentItemController 是:
@RestController
@RequestMapping("/contentItems")
public class ContentItemController {
@Autowired
private ContentItemService contentItemService;
@GetMapping("/{contentItemId}")
public Mono<ResponseEntity<ContentItem>> getContentItemByUserId(@PathVariable Integer contentItemId){
Mono<ContentItem> contentItem = contentItemService.getContentItemById(contentItemId);
return contentItem.map( u -> ResponseEntity.ok(u))
.defaultIfEmpty(ResponseEntity.notFound().build());
}
我的 ContentItemService 是:
@Service
@Slf4j
@Transactional
public class ContentItemService {
@Autowired
private ContentItemRepository contentItemRepository;
public Mono<ContentItem> getContentItemById(Integer contentItemId){
return contentItemRepository.findByContentItemId(contentItemId);
}
}
我的 ContentItemRepository 是:
public interface ContentItemRepository extends ReactiveCrudRepository<ContentItem,Integer> {
Mono<ContentItem> findByContentItemId(Integer contentItemId);
}
当我使用 http://localhost:8081/contentItems/1
调用 运行 服务时,我在 GET 上收到 500 服务器错误并且在日志中收到以下内容:
org.springframework.data.r2dbc.BadSqlGrammarException: executeMany; bad SQL grammar [SELECT contentitem.content_item_id, contentitem.localized_name FROM contentitem WHERE contentitem.content_item_id = ]; nested exception is io.r2dbc.spi.R2dbcBadGrammarException: [42122] [42S22] Column "CONTENTITEM.CONTENT_ITEM_ID" not found; SQL statement:
几个问题:
- 为什么我的简单、明确、一致的列名(例如 'contentItemId')被破坏成它们自己的带下划线的版本(例如 'CONTENT_ITEM_ID')?只是为了笑,我尝试在 'contentItemId' 数据成员上方添加一个 '@Column("content_item_id")' 注释,但得到了相同的结果。
- 为什么找不到 'contentItemId'(或 'CONTENT_ITEM_ID')列?
使这一切复杂化的是,我在 application.properties 文件中使用 spring.h2.console.enabled=true
启用的 H2 控制台失败,当我使用 http://localhost:8081/h2-console
.
您需要在您的实体中使用列注释class
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table("contentitem")
public class ContentItem {
@Id
@Column("contentItemId")
private Integer contentItemId;
@Column("localizedName")
private String localizedName;
}
或者您应该用 _
命名列
CREATE TABLE contentitem ( content_item_id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, localized_name VARCHAR(100) NOT NULL);
我使用 WebFlux 反应模块、H2 内存数据库和 R2DBC 反应驱动程序创建了 Java Spring 引导服务。这在端口 8081 上构建并运行良好。
我在 main/resources 下添加了一个 schema.sql 文件,其中包含以下内容:
CREATE TABLE contentitem ( contentItemId INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, localizedName VARCHAR(100) NOT NULL);
我在同一目录中使用 data.sql 文件填充 table:
INSERT INTO contentitem (contentItemId, localizedName) VALUES (0, 'Zero');
INSERT INTO contentitem (contentItemId, localizedName) VALUES (1, 'One');
INSERT INTO contentitem (contentItemId, localizedName) VALUES (2, 'Two');
我的 ContentItem 模型是:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table("contentitem")
public class ContentItem {
@Id
private Integer contentItemId;
private String localizedName;
我的 ContentItemController 是:
@RestController
@RequestMapping("/contentItems")
public class ContentItemController {
@Autowired
private ContentItemService contentItemService;
@GetMapping("/{contentItemId}")
public Mono<ResponseEntity<ContentItem>> getContentItemByUserId(@PathVariable Integer contentItemId){
Mono<ContentItem> contentItem = contentItemService.getContentItemById(contentItemId);
return contentItem.map( u -> ResponseEntity.ok(u))
.defaultIfEmpty(ResponseEntity.notFound().build());
}
我的 ContentItemService 是:
@Service
@Slf4j
@Transactional
public class ContentItemService {
@Autowired
private ContentItemRepository contentItemRepository;
public Mono<ContentItem> getContentItemById(Integer contentItemId){
return contentItemRepository.findByContentItemId(contentItemId);
}
}
我的 ContentItemRepository 是:
public interface ContentItemRepository extends ReactiveCrudRepository<ContentItem,Integer> {
Mono<ContentItem> findByContentItemId(Integer contentItemId);
}
当我使用 http://localhost:8081/contentItems/1
调用 运行 服务时,我在 GET 上收到 500 服务器错误并且在日志中收到以下内容:
org.springframework.data.r2dbc.BadSqlGrammarException: executeMany; bad SQL grammar [SELECT contentitem.content_item_id, contentitem.localized_name FROM contentitem WHERE contentitem.content_item_id = ]; nested exception is io.r2dbc.spi.R2dbcBadGrammarException: [42122] [42S22] Column "CONTENTITEM.CONTENT_ITEM_ID" not found; SQL statement:
几个问题:
- 为什么我的简单、明确、一致的列名(例如 'contentItemId')被破坏成它们自己的带下划线的版本(例如 'CONTENT_ITEM_ID')?只是为了笑,我尝试在 'contentItemId' 数据成员上方添加一个 '@Column("content_item_id")' 注释,但得到了相同的结果。
- 为什么找不到 'contentItemId'(或 'CONTENT_ITEM_ID')列?
使这一切复杂化的是,我在 application.properties 文件中使用 spring.h2.console.enabled=true
启用的 H2 控制台失败,当我使用 http://localhost:8081/h2-console
.
您需要在您的实体中使用列注释class
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table("contentitem")
public class ContentItem {
@Id
@Column("contentItemId")
private Integer contentItemId;
@Column("localizedName")
private String localizedName;
}
或者您应该用 _
命名列CREATE TABLE contentitem ( content_item_id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, localized_name VARCHAR(100) NOT NULL);