Spring Data JPA存储库方法无法识别带下划线的属性名称

lio*_*nyu 6 spring-data-jpa

我在实体属性名称中有下划线,当Spring尝试创建JPA存储库实现时,它会导致尝试解析属性名称的异常.

实体:

@Entity
public class Student {
      @Id
      private String s_id;
      private String s_name;
      ...
}
Run Code Online (Sandbox Code Playgroud)

库:

 @Repository
 @Transactional
 public interface StudentRepository extends CrudRepository<Student, String> {

       List<Student> findByS__name(String name);

}
Run Code Online (Sandbox Code Playgroud)

例外:

org.springframework.data.mapping.PropertyReferenceException: 
No property s found for type Student
Run Code Online (Sandbox Code Playgroud)

这里说http://docs.spring.io/spring-data/jpa/docs/current/reference/html/

如果您的属性名称包含下划线(例如first_name),则可以使用第二个下划线转义方法名称中的下划线.对于first_name属性,查询方法必须命名为findByFirst__name(...).

我只是按照文件说的那样做,但我仍然有例外.我不想@Query自己写,我需要在我的属性名称下划线,如何解决这个问题?

我使用Spring数据jpa 1.8.0.RELEASE + hibernate 4.3.9.Final

Jos*_*ull 9

如果您可以控制属性命名,请避免在实体属性名称中使用下划线.这将解决您的存储库问题,并将产生更清晰的代码库.处理完代码的开发人员会感谢你.

请注意,这不仅仅是我的观点:Spring特别不鼓励使用下划线.

由于我们将下划线视为保留字符,因此我们强烈建议遵循标准Java命名约定(即不在属性名称中使用下划线而是使用camel case).

此JIRA问题显示了为什么文档已使用此推荐更新,并且删除了描述双下划线选项的部分.

我怀疑你的根本问题是Spring/Hibernate没有将camel case属性名称映射到数据库中列的蛇案例名称.您真正需要的是在Hiberate生成为S_NAME的SQL中解释您的属性名称.

这就是为什么你的房产名称中的下划线是"必需的"?如果是这样,有一些解决方案:

选项1:@Column注释

要让JPA/Hibernate映射到正确的列名,您可以明确地告诉它名称.使用注释@Column(name="...")告诉它在SQL中使用哪些列名.然后字段名称不受列名约束.

@Entity
public class Student {
     @Id
     @Column(name="s_id")
     private String sId;
     @Column(name="s_name")
     private String sName;

     //...getters and setters...
}
Run Code Online (Sandbox Code Playgroud)

选项2:改进的命名策略
或者如果您的应用程序具有大量实体,而不是添加@Column到每个属性,请将配置文件中的默认命名策略更改为hibernate改进的命名策略.

<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
Run Code Online (Sandbox Code Playgroud)

此命名策略将camelCase转换为SNAKE_CASE.然后你的课可以看起来像这样简单:

@Entity
public class Student {
     @Id
     private String sId;
     private String sName;

     //...getters and setters...
}
Run Code Online (Sandbox Code Playgroud)

使用其中任何一个选项,在创建SQL时,它会将列名称解析为:

 S_ID
 S_NAME
Run Code Online (Sandbox Code Playgroud)

注意:如果您正在使用,或者可以使用Spring Boot,则自动配置默认将使用SpringNamingStrategy,这是hibernate改进策略的略微修改版本.您无需采取任何措施来获得这种改进的命名策略.

终点线:

在您的属性名称中使用驼峰大小写,您可以使用camel case编写存储库方法名称,并且可以停止尝试使用双下划线进行争论:

@Repository
@Transactional
public interface StudentRepository extends CrudRepository<Student, String> {  
       List<Student> findBySName(String name);   
}
Run Code Online (Sandbox Code Playgroud)


小智 5

编写双下划线,即为属性名称 s_name 编写 findByS__Name() 是行不通的。我已经尝试过并测试过了。按照上面的答案并更改实体类中现有实例变量的名称。只是不要更改 getter 和 setter,因为它们可能会在现有代码中使用。