JPA与Hibernate中实体和视图作为双父类的一对多关系建模问题
解决JPA视图实体关联已有子实体的映射异常问题
你遇到的这个异常核心原因是:JPA要求mappedBy指定的反向关联字段必须指向当前实体类型——PostComment里的post字段关联的是Post实体,而你在PostView里用它来映射评论列表,类型不匹配才会报错。下面给你几个不用修改PostComment的简洁解决方案:
方案1:显式配置关联列(推荐,符合JPA规范)
直接抛弃mappedBy,用@JoinColumn显式指定关联的外键列,同时指定目标实体类型;因为PostView是不可变视图,还要设置insertable=false和updatable=false避免JPA尝试修改数据:
@Entity @Immutable @Table(name = "view_post") public class PostView { @Id private Long id; // 省略其他字段... @OneToMany(targetEntity = PostComment.class) @JoinColumn(name = "post_id", referencedColumnName = "id", insertable = false, updatable = false) private List<PostComment> comments; }
方案2:通过Repository查询获取评论
不在实体类中映射关联关系,而是在PostView的Repository里写查询方法直接获取对应评论:
public interface PostViewRepository extends JpaRepository<PostView, Long> { @Query("SELECT pc FROM PostComment pc WHERE pc.post.id = :postId") List<PostComment> findCommentsByPostId(@Param("postId") Long postId); }
这种方式更灵活,适合不需要在实体中直接持有评论集合的场景。
方案3:利用Hibernate的@Where注解(依赖Hibernate扩展)
如果你的JPA实现是Hibernate,可以用@Where添加过滤条件,结合targetEntity指定目标类型:
@Entity @Immutable @Table(name = "view_post") public class PostView { @Id private Long id; // 省略其他字段... @OneToMany(targetEntity = PostComment.class) @Where(clause = "post_id = id") private List<PostComment> comments; }
注意这个方案依赖Hibernate的扩展注解,通用性不如方案1。
内容的提问来源于stack exchange,提问作者Robert Strauch
相关产品推荐
相关产品推荐

