Spring Boot创建roleJpaRepository Bean报错:RoleEntity无role属性
错误详情
运行版本2.2.6.RELEASE的Spring Boot应用时,出现如下错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roleJpaRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract com.microservices.entity.RoleEntity com.microservices.repo.RoleJpaRepository.findByRole_name(java.lang.String)! No property role found for type RoleEntity!
问题原因
Spring Data JPA的方法命名解析规则是驼峰式匹配实体类属性:当你写findByRole_name时,JPA会将Role识别为实体类的一个属性名,但你的RoleEntity中并没有名为role的属性,只有下划线命名的role_name,因此触发属性不存在的错误。
解决方案
方案1:统一使用驼峰式命名(推荐)
修改实体类属性名和Repository方法名,遵循Java驼峰命名规范:
修改后的RoleEntity
import lombok.*; import org.hibernate.Hibernate; import javax.persistence.*; @Entity(name="role") @Getter @Setter @ToString @NoArgsConstructor @AllArgsConstructor public class RoleEntity { @Id @SequenceGenerator( name = "role_sequence", sequenceName = "role_sequence", allocationSize = 1 ) @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "role_sequence" ) @Column( name = "id", updatable = false, unique = true, nullable = false ) private int id; // 将属性名改为驼峰式roleName,数据库列名仍保持role_name @Column( name = "role_name", unique = true, nullable = false, columnDefinition = "TEXT" ) private String roleName; @Override public boolean equals(Object o) { if (this == o) return true; if (o != null) { Hibernate.getClass(this); Hibernate.getClass(o); } return false; } @Override public int hashCode() { return getClass().hashCode(); } }
修改后的RoleJpaRepository
import com.microservices.entity.RoleEntity; import org.springframework.data.jpa.repository.JpaRepository; public interface RoleJpaRepository extends JpaRepository<RoleEntity, Integer> { // 方法名改为findByRoleName,匹配驼峰属性 RoleEntity findByRoleName(String roleName); }
方案2:保留下划线命名,使用@Query自定义查询
如果不想修改命名风格,可以直接用@Query注解编写SQL查询,绕过JPA的方法命名解析:
import com.microservices.entity.RoleEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; public interface RoleJpaRepository extends JpaRepository<RoleEntity, Integer> { @Query("SELECT r FROM role r WHERE r.role_name = ?1") RoleEntity findByRole_name(String role_name); }
方案3:配置JPA适配下划线命名
在application.properties中添加配置,让JPA自动将驼峰方法名映射为下划线列名:
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
配置后,Repository方法可以写成findByRoleName,JPA会自动映射到数据库的role_name列,无需修改实体类属性名。
内容的提问来源于stack exchange,提问作者CuriousMe

