查询餐厅信息时提示表'restaurant-service.food_menu'不存在,求解决方案
问题
调用/showAllRestaurants接口获取所有餐厅信息时,抛出错误:Table 'restaurant-service.food_menu' doesn't exist,但/create接口(POST请求创建餐厅)可以正常执行,数据库中实际存在名为FoodMenu的表。
相关代码
领域模型
Restaurant 实体
@Getter @Setter @NoArgsConstructor @Entity @Table(name = "Restaurant") public class Restaurant { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "RESTAURANT_ID") private Long id; private String restaurantName; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "restaurant") private List<FoodMenu> menu; @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "ADDRESS_ID") private Address address; }
FoodMenu 实体
@Getter @Setter @NoArgsConstructor @Entity @Table(name = "FoodMenu") public class FoodMenu { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "FOOD_MENU_ID") private Long id; private String foodName; private String foodDescription; private BigDecimal foodPrice; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "RESTAURANT_ID") private Restaurant restaurant; }
服务层
@Service @Transactional public class RestaurantService { @Autowired private RestaurantRepository restaurantRepository; public void saveRestaurant(Restaurant restaurant){ restaurantRepository.save(restaurant); } public List<Restaurant> allRestaurants(){ return restaurantRepository.findAll(); } }
控制层
@RestController public class RestaurantController { @Autowired private RestaurantService restaurantService; @PostMapping("/create") public void createUploadRestaurant(@RequestBody Restaurant restaurant){ restaurantService.saveRestaurant(restaurant); } @GetMapping("/showAllRestaurants") public List<Restaurant> showRestaurants(){ return restaurantService.allRestaurants(); } }
问题原因与解决办法
原因
Hibernate默认会将驼峰式命名的实体类转换为下划线分隔的小写表名(比如FoodMenu转为food_menu),当数据库开启大小写敏感(如Linux环境下的MySQL)时,就会找不到实际的FoodMenu表。而POST请求正常,是因为创建数据时若开启了ddl-auto为create或update,Hibernate可能自动创建了适配的表,但查询时仍使用默认命名策略查找错误表名。
解决办法
修改Hibernate命名策略:
在application.properties中添加配置,强制Hibernate严格使用@Table注解指定的表名:spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl统一表名大小写:
将数据库中的FoodMenu表重命名为food_menu,和Hibernate默认转换后的表名一致。调整数据库大小写配置:
若使用MySQL,修改my.cnf中的lower_case_table_names参数为1(表名转为小写存储),重启数据库后即可匹配Hibernate的默认命名策略。
内容的提问来源于stack exchange,提问作者Lamvegan
相关产品推荐
相关产品推荐

