Spring Data JPA测试中@MappedSuperClass属性查询列不存在问题
解决Spring Data JPA原生查询@MappedSuperClass属性时的列不存在问题
问题根源
核心问题出在Hibernate的物理命名策略转换:默认情况下,Hibernate会把Java类中驼峰命名的属性(比如tweetType)转换成数据库里下划线分隔的列名(比如tweet_type)。而你在原生SQL查询中直接使用了Java属性名tweetType,数据库自然找不到对应的列。
虽然@MappedSuperclass的属性会被实体继承并映射到同一张表,但这只是JPA层面的逻辑映射,数据库里的实际列名还是由Hibernate的命名策略决定的。
解决方案
这里提供三种可行的解决方式,按需选择:
1. 原生SQL中使用实际数据库列名
直接把查询语句里的tweetType改成数据库实际列名tweet_type即可:
@Repository public interface TweetRepository extends JpaRepository<Tweet, Long> { @Query(value = "SELECT * FROM tweet WHERE tweet_type = ?1", nativeQuery = true) List<Tweet> findAllCircleTweets(String type); }
2. 显式指定属性对应的列名
如果希望数据库列名和Java属性名保持一致(比如都用tweetType),可以在@MappedSuperclass的属性上添加@Column注解指定列名:
@MappedSuperclass public class TweetMetadata { @Column(name = "tweetType") private String tweetType; @CreatedDate private LocalDateTime created; }
这样Hibernate会将tweetType属性映射为数据库的tweetType列,原生SQL里用tweetType就不会报错了。
3. 使用JPQL替代原生SQL(推荐)
JPQL是面向实体的查询语言,直接使用Java属性名即可,Hibernate会自动帮你转换成对应的数据库列名,避免硬编码列名的问题:
@Repository public interface TweetRepository extends JpaRepository<Tweet, Long> { @Query("SELECT t FROM Tweet t WHERE t.tweetType = ?1") List<Tweet> findAllCircleTweets(String type); }
这种方式更符合JPA的设计理念,也能避免后续实体属性修改时同步修改SQL的麻烦。
验证说明
从你提供的报错日志也能看出:Hibernate生成的插入语句用的是tweet_type列,而你的自定义查询用了tweetType,两者不匹配导致报错。只要让查询语句里的列名和数据库实际列名一致,问题就能解决。
内容的提问来源于stack exchange,提问作者Samuel Owino
相关产品推荐
相关产品推荐

