49

I am using spring-data-jpa on a spring webmvc project. I am facing an issue using query creation on a Repository of one of my Entities. Below you can see my Entity, my Repository and the Exception.

My Entity:

@Entity
@Table(schema = "mainschema")
@XmlRootElement
public class Municipalperson implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(nullable = false)
    private Integer id;

    @Basic(optional = false)
    @Column(name = "municipal_id", nullable = false)
    private Integer municipal_id;

    @Basic(optional = false)
    @Column(nullable = false, length = 60)
    private String firstname;

    public Municipalperson(Integer id, Integer municipal_id, String firstname) {
        this.id = id;
        this.municipal_id = municipal_id;
        this.firstname = firstname;
    }


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getMunicipal_id() {
        return municipal_id;
    }

    public void setMunicipal_id(Integer municipal_id) {
        this.municipal_id = municipal_id;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
}

my Repository:

@Repository
public interface MunicipalpersonRepository extends JpaRepository<Municipalperson, Integer> {

    List<Municipalperson> findByMunicipal_idOrderByLastnameDesc(int municipal_id);
}

and the exception,

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'municipalpersonRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property municipal found for type Municipalperson!  

I tried to set municipal_id as int, then as Integer and the same for the parameter municipal_id on my Repository, but none worked. Also, I renamed the Repository to findByMunicipalidOrderByLastnameDesc and findByMunicipalIdOrderByLastnameDesc but it didn't work either.

Finally I renamed the municipal_id to municipalId (underscore removed) and also renamed getters/setters and the Repository (findByMunicipalIdOrderByLastnameDesc) and the issue was resolved.

My question is why this is happening?

2
  • 2
    Spring Data JPA heavily relies on Java naming conventions. You chose not to respect them by having an underscore in your field and accessor names. That's why you got bitten. Respect the Java naming conventions, and Spring Data JPA will be happy, and your code will be more readable as a bonus. Not that the column can be named as you want, including with underscores. What matters is your mapped field names. Commented May 4, 2014 at 12:31
  • Thank you very much for your comment. I didn't know about the java naming conventions. I found, also, this stackoverflow question that helped me too. Commented May 4, 2014 at 12:38

6 Answers 6

67

I solved this error by renaming field to the name without underscore.

@Column(name = "municipal_id", nullable = false)
private Integer municipalId; // <-- field was renamed
Sign up to request clarification or add additional context in comments.

5 Comments

This really is the best way to handle this scenario and should be the accepted answer. I realize this answer came a few years after the question and first answer, but am putting this comment to draw attention of future visitors to this answer. Solving in this manner allows you to work with databases that name fields in a way you cannot control, without deviating from the coding standards which are generally accepted across the entire field of java developers, e.g. keeps underscores entirely out of your method and variable names.
Best way to remove error without changing database and all the mapping stuff.
Answering the first comment, the question was not "how to map a db column name with underscore to a Java Entity" but how to use an entity property with an underscore with spring-data. That's why this answer is not the accepted.
this answer should be marked as correctly one, a very small effort to overcome problem.
Indeed, I agree with all comments, this answer is the smarter one : no database alteration.
48

The underscore _ is a reserved character in Spring Data query derivation (see the reference docs for details) to potentially allow manual property path description. So there are two options you have:

  1. Stick to the Java naming conventions of using camel-case for member variable names and everything will work as expected.
  2. Escape the _ by using an additional underscore, i.e. rename your query method to findByMunicipal__idOrderByLastnameDesc(…).

I'd recommend the former as you're not going to alienate fellow Java developers :).

6 Comments

This does not work. Double underscore does not change anything. And fields in Java JPA object just follow the name of the fields in database that obviously does not follow Java convention. So that must be a pretty common use case.
The double underscore solution did not worked for me too and I am not able to undo my upvote...
The double underscore did not work for me, but I also see many upvotes. Perhaps the answer can be improved by listing the conditions required for this to work, so those for whom it doesn't apply don't attempt this solution?
The answer is fine. Just use option 1. People spent way too much time working on conventions and providing support for it so it becomes useful. The only problem with the answer is that option 2 is mentioned, it shouldn't.
Option 1 is sometimes not possible, especially when you work with code that is supposed to follow format guidelines and which verification is done as part of the build, some code conventions in some companies require you to use prefix instance variables with "_" to differentiate them from method local variables and to avoid idioms like this.myVar = myVar which can become smelly. Jagannath's answer covers those cases.
|
7

Please add the following properties to application.properties file:

spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy

2 Comments

This works well and requires no other changes. From: docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/cfg/…: org.hibernate.cfg.ImprovedNamingStrategy is an improved naming strategy that prefers embedded underscores to mixed case names.
spring.jpa.hibernate.naming-strategy is an unknown property error
3

According to the Docs, underscore is a special character used by spring to separate properties names. If you really want to stick with snake case notation, you can set nativeQuery to true:

@Query(value = "SELECT * FROM municipalperson WHERE municipal_id=?1 ORDER BY last_name DESC", nativeQuery = true)
List<Municipalperson> findByMunicipal_idOrderByLastnameDesc(int municipal_id);

1 Comment

Same thing happens with native queries
2

One other approach that worked for me is to use @JsonProperty to differentiate between field name used in REST request/response and that used for database. For example:

@JsonProperty("municipalId")
private Integer municipal_id;

1 Comment

This doesn't work when the input type is of NON JSON type ex.: application/form-urlencoded and so on .....
0

Refer to the official documentation here:

Because we treat the underscore character as a reserved character, we strongly advise following standard Java naming conventions (that is, not using underscores in property names but using camel case instead).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.