I had a simple field like pId, and it can used in jpa repository like :

List<Company> findByPId(Integer pid);

It can work When I import:

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>2.0.8.RELEASE</version>
      </dependency>

Then I update the project level now:

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>2.1.13.RELEASE</version>
      </dependency>

But It can't work anymore. Here is startup error message:

Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [PId] on this ManagedType [a.Company]
 at org.hibernate.metamodel.internal.AbstractManagedType.checkNotNull(AbstractManagedType.java:128)
 at org.hibernate.metamodel.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:113)
 at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:634)
 at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:618)
 at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.getTypedPath(JpaQueryCreator.java:384)
 at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:276)
 at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:210)
 at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:123)
 at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:58)
 at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:119)
 at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95)
 at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:81)
 at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.<init>(PartTreeJpaQuery.java:147)
 at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$CountQueryPreparer.<init>(PartTreeJpaQuery.java:270)
 at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:79)
 ... 70 common frames omitted
  • Question How can i use like it again? Or should I add some properties?

Comment From: zero3h

I debug the source core and find something different bewteen 2.0.x and 2.1.x, here is core: - Jar: spring-data-commons-2.0.13.RELEASE.jar - Class: org.springframework.data.repository.query.parser.Part

public String extractProperty(String part) {

    String candidate = StringUtils.uncapitalize(part);

    for (String keyword : keywords) {
        if (candidate.endsWith(keyword)) {
            return candidate.substring(0, candidate.length() - keyword.length());
        }
    }

    return candidate;
}

Tool Class: org.springframework.util.StringUtils

public static String uncapitalize(String str) {
    return changeFirstCharacterCase(str, false);
}

private static String changeFirstCharacterCase(String str, boolean capitalize) {
    if (!hasLength(str)) {
        return str;
    }

    char baseChar = str.charAt(0);
    char updatedChar;
    if (capitalize) {
        updatedChar = Character.toUpperCase(baseChar);
    }
    else {
        updatedChar = Character.toLowerCase(baseChar);
    }
    if (baseChar == updatedChar) {
        return str;
    }

    char[] chars = str.toCharArray();
    chars[0] = updatedChar;
    return new String(chars, 0, chars.length);
}

The updated version: - Jar: spring-data-commons-2.1.14.RELEASE.jar - Class: org.springframework.data.repository.query.parser.Part

public String extractProperty(String part) {

    String candidate = Introspector.decapitalize(part);

    for (String keyword : keywords) {
        if (candidate.endsWith(keyword)) {
            return candidate.substring(0, candidate.length() - keyword.length());
        }
    }

    return candidate;
}
  • Tool Class: java.beans.Introspector
public static String decapitalize(String name) {
    if (name == null || name.length() == 0) {
        return name;
    }
    if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                    Character.isUpperCase(name.charAt(0))){
        return name;
    }
    char chars[] = name.toCharArray();
    chars[0] = Character.toLowerCase(chars[0]);
    return new String(chars);
}

So I think that's the problem.

I rewrite the class Part to use StringUtils.uncapitalize(String str) now, will it be fixed in a future version in 2.1.x?

Comment From: wilkinsona

@zero3h Thanks for the report and problem diagnosis. Spring Data Commons is managed as a separate project. The change was made to fix DATACMNS-1570. I believe you can avoid the problem by renaming the property or by adding a @Query to the method. If you require any further guidance, please follow up with the Spring Data team on Gitter or Stack Overflow.