JPA报错No property found for type的问题

Solve the exception for JPA No property found for type problem

Posted by qingshan on November 25, 2019

在 JPA 中定义完 model 和 dao 之后,JPA 会自动检索 model,然后生成 findByFieldName 的方法。

例如,定义了一个字段叫 actionid,JPA 在 repository 文件里,会自动创建 findByActionid 的方法,意思是根据 actionid 这个字段来查询,获得结果。

但是,如果字段是带下划线"_"的时候,生成的方法是 findByAction_id,结果 100% 会报错,提示:

1
No property action found for type Action!

这是因为 JPA 虽然会生成 findByAction_id,但是 Spring 却不会认下划线,最终是按照下划线前的关键字,也就是action来解析,model 和数据库里没有这个字段,当然会报错了。

经过实践,有两种方式解决这个问题:

1. @Column 别名指定

在创建 model 的时候,可以使用@Column 指定数据库实际的字段,那么定义 model 字段名的时候,就可以设置任意别名了。例如:

1
2
3
4
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Action_ID")
    private Integer actionid;

定义的字段是 actionid,没有下划线,但是实际上映射到数据库是 Action_ID 这个字段是有下划线的。但是这个过程已经是在查询的最后阶段,不会影响程序运行,完美解决问题。

2. @Query 指定 SQL

如果方法 1 不能满足业务需求,可以使用@Query 在 repository 中来指定方法所执行的 SQL 语句,覆盖原来自动方法。例如:

1
2
3
4
public interface TableMigratePolicyRepository extends JpaRepository<TableMigratePolicy, String> {
    @Query("SELECT t FROM TableMigratePolicy t WHERE t.action_id = 0 or t.comment is not null or t.comment <> '' ")
    List<TableMigratePolicy> findByAction_id(Integer action_id);
}

这时候,即使方法名里有下划线,但是实际运行的是@Query里执行的 SQL 语句,也会避免报错的问题。