Spring Data JPA repository methods don't recognize property names with underscores

lionyu

I have underscores in the entity property names, and when Spring tries to create the JPA repository implementation, it results in an exception trying to resolve the name of the property.

Entity:

@Entity
public class Student {
      @Id
      private String s_id;
      private String s_name;
      ...
}

Repository:

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

       List<Student> findByS__name(String name);

}

Exception:

org.springframework.data.mapping.PropertyReferenceException: 
No property s found for type Student

It is said here http://docs.spring.io/spring-data/jpa/docs/current/reference/html/

If your property names contain underscores (e.g. first_name) you can escape the underscore in the method name with a second underscore. For a first_name property the query method would have to be named findByFirst__name(…).

I just did as document said, but I still got the exception. I dont want write @Query by myself, and I need underscore in my property name, how to fix this problem?

I use Spring data jpa 1.8.0.RELEASE + hibernate 4.3.9.Final

Josh Hull

Avoid using underscores in the entity property names if you have control over the property naming. This will resolve your repository woes, and will result in a cleaner code-base. Developers dealing with the code after you will thank you.

Note, it's not just my opinion: Spring specifically discourages using underscores.

As we treat underscore as a reserved character we strongly advise to follow standard Java naming conventions (i.e. not using underscores in property names but camel case instead).

this JIRA issue shows why the documentation was updated with this reccomendation, and the part describing the double underscore option were removed.

I suspect your root problem is that Spring/Hibernate is not mapping camel case property names to the snake case names you have for your columns in the database. What you really need is for your property name to be interpreted in the SQL that hiberate generates as S_NAME.

Is that why underscores in your property name are "required"? If so, there are a few solutions:

Option 1: @Column annotation

To get JPA/Hibernate to map to the correct column names you can tell it the names explicitly. Use the annotation @Column(name="...") to tell it what column names to use in SQL. Then the field names are not constrained by the column names.

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

     //...getters and setters...
}

Option 2: Improved Naming Strategy
Or if your application has a large number of entities, rather than adding @Column to every property, change the default naming strategy in your configuration file to the hibernate improved naming strategy.

<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>

This naming strategy will convert camelCase to SNAKE_CASE. Then your class could look as simple as this:

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

     //...getters and setters...
}

Using either of those options, when it creates the SQL it will resolve the column names to:

 S_ID
 S_NAME

Note: If you are using, or can use Spring Boot, the auto-configuration default will use SpringNamingStrategy, which is a slightly modified version of the hibernate improved strategy. You won't have to do anything to get this improved naming strategy.

The finish line:

Using camel case in your property names you can write your repository method name using camel case, and you can stop trying to wrangle the double underscore:

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

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Spring Data JPA repository throws null pointer

How to instrument / advice a Spring Data (JPA) repository?

No property found for type error when try to create custom repository with Spring Data JPA

How does Spring Data JPA resolve property name containing single letter abbreviation for a word in query methods?

Configure Pointcut for Spring JPA repository methods

Create Custom Repository to Spring Data JPA

Derived methods in spring data jpa

Spring Boot JPA, Repository don't delete record

Spring data jpa custom repository with pageable

where does spring jpa repository store data?

find by id in spring data jpa Base Repository

using spring data jpa repository if there is no primary key

Spring Data JPA: Example from Spring in Action don't run

Repository annotation is not working on Spring data JPA

spring-data-jpa implements repository for you

Spring Data JPA repository method with property name containing a special word

Trouble creating Spring Data JPA repository

How to set up Spring Data JPA Repository?

Spring JPA repository cannot resolve property of entity

Spring Data JPA Repository Interface Implementaion

Spring Data JPA doesn't specify lower keyword in method names

Java repository - Spring Data JPA

Spring data jpa repository find by multi elements

Spring integration jpa repository tests don't work as it should

Spring JPA data repository not acting like it should

Spring Batch/Data JPA application not persisting/saving data to Postgres database when calling JPA repository (save, saveAll) methods

How to create bean for spring data jpa repository?

Spring Data JPA : Efficient Way to Invoke Repository Methods with Optional Parameters

Handling data differently in JPA based on repository methods