Spring Boot中如何通过外键关联查询另一表字段
问题解决:无法展示城市关联的国家名称
核心问题分析
代码中存在几个关键错误导致无法获取并展示国家名称:
- 实体类类型不匹配:City类中关联属性
countries的类型是Country,但手动编写的getter/setter却使用Countries类型,导致无法正确获取关联对象。 - 重复的getter/setter:Lombok的
@Data注解已经自动生成标准的getter/setter,手动编写的方法不仅冗余,还存在命名不规范(如getcity_name不符合JavaBean规范)和类型错误的问题。 - 关联数据加载问题:默认情况下
@ManyToOne是立即加载,但如果存在持久化上下文关闭的情况,懒加载会导致无法访问关联的国家数据。
修复步骤及代码示例
1. 修正City实体类
删除手动编写的getter/setter,确保关联属性类型一致,并显式指定关联数据加载策略:
package com.bookflight.BookFlight.gradovi; import com.bookflight.BookFlight.drzave.Country; // 确保导入正确的Country类 import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = "cities") public class City { @Id @Column(name = "city_id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(nullable = false, length = 45, name = "city_name") private String city_name; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "cou_id", referencedColumnName = "cou_id") private Country countries; }
2. 优化Repository层(可选,确保关联数据主动加载)
如果需要更灵活的关联查询,在Repository中定义主动加载国家数据的方法:
public interface CityRepository extends JpaRepository<City, Integer> { @Query("SELECT c FROM City c JOIN FETCH c.countries") List<City> findAllWithCountries(); }
3. 更新服务层方法
调用自定义的查询方法确保加载关联数据:
public List<City> listAll() { List<City> cities = repo.findAllWithCountries(); return cities; }
4. 视图层获取国家名称
假设使用Thymeleaf模板,通过对象嵌套属性访问国家名称(需确保Country实体有对应的名称属性,如country_name):
<table> <tr> <th>城市ID</th> <th>城市名称</th> <th>所属国家</th> </tr> <tr th:each="city : ${showListCities}"> <td th:text="${city.id}"></td> <td th:text="${city.city_name}"></td> <td th:text="${city.countries.country_name}"></td> </tr> </table>
注意事项
- 确认Country实体类中存在
country_name(或对应名称)的属性,且Lombok的@Data注解已生成正确的getter方法。 - 若使用懒加载(
FetchType.LAZY),需确保视图层访问关联属性时持久化上下文未关闭,可依赖Spring Boot默认开启的Open Session in View模式。
内容的提问来源于stack exchange,提问作者Aleksso
相关产品推荐
相关产品推荐

