spring-projects / spring-data-jpa

Simplifies the development of creating a JPA-based data access layer.
https://spring.io/projects/spring-data-jpa/
Apache License 2.0
3.01k stars 1.42k forks source link

Failed to create query for method @Embeddable obj's field with prefix. [DATAJPA-1390] #1709

Closed spring-projects-issues closed 3 years ago

spring-projects-issues commented 6 years ago

hkanali opened DATAJPA-1390 and commented

Since spring-boot v2.0.3 (spring-data-jpa:2.0.8) , Query method creation from method name does not work.

Specified field name of method name is prefixed name (e.g. mShopId).

// Entity
@Entity
public class ShopCustomer {

    @EmbeddedId
    private Id id;
    private Date visitedDate;

    protected ShopCustomer() {}

    public ShopCustomer(Long mShopId, Long customerId, Date visitedDate) {
        this.id = new Id(mShopId, customerId);
        this.visitedDate = visitedDate;
    }

    public Id getId() {
        return id;
    }

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

    public Date getVisitedDate() {
        return visitedDate;
    }

    public void setVisitedDate(Date visitedDate) {
        this.visitedDate = visitedDate;
    }

    @Override
    public String toString() {
        return String.format(
                "ShopCustomer[id='%s', visitedDate='%s']",
                id, visitedDate);
    }

    @Embeddable
    public static class Id implements Serializable {

        private static final long serialVersionUID = 1L;

        /**
         * 'm' means 'M'aster data.
         */
        private Long mShopId;

        private Long customerId;

        protected Id() {}

        public Id(Long mShopId, Long customerId) {
            this.mShopId = mShopId;
            this.customerId = customerId;
        }

        public Long getmShopId() {
            return mShopId;
        }
        public void setmShopId(Long mShopId) {
            this.mShopId = mShopId;
        }

        public Long getCustomerId() {
            return customerId;
        }
        public void setCustomerId(Long customerId) {
            this.customerId = customerId;
        }

        @Override
        public String toString() {
            return "Id [mShopId=" + mShopId + ", customerId=" + customerId + "]";
        }
    }
}

 

// Repository
public interface ShopCustomerRepository extends CrudRepository<ShopCustomer, ShopCustomer.Id> {

    /**
     * spring boot v2.0.2.RELEASE (depended spring-data-jpa:2.0.7.RELEASE) works.
     * spring boot v2.0.3.RELEASE (depended spring-data-jpa:2.0.8.RELEASE) does not work.
     */
    List<ShopCustomer> findByIdMShopId(Long mShopId);
}
// Tests
@RunWith(SpringRunner.class)
@DataJpaTest
public class ShopCustomerRepositoryTests {
    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private ShopCustomerRepository shopCustomers;

    @Test
    public void testFindByIdMShopId() {
        ShopCustomer shopCustomer = new ShopCustomer(1L, 2L, new Date());
        entityManager.persist(shopCustomer);

        List<ShopCustomer> findByIdMShopId = shopCustomers.findByIdMShopId(shopCustomer.getId().getmShopId());

        // failed when spring boot 2.0.3.
        assertThat(findByIdMShopId).asList().isNotEmpty();
    }
}
1. Stacktraces
Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [MShopId] on this ManagedType [unknown]
    at org.hibernate.metamodel.internal.AbstractManagedType.checkNotNull(AbstractManagedType.java:128) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.metamodel.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:113) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.query.criteria.internal.path.SingularAttributePath.locateAttributeInternal(SingularAttributePath.java:71) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.query.criteria.internal.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:204) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.query.criteria.internal.path.AbstractPathImpl.get(AbstractPathImpl.java:177) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:648) ~[spring-data-jpa-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:596) ~[spring-data-jpa-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.getTypedPath(JpaQueryCreator.java:378) ~[spring-data-jpa-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:301) ~[spring-data-jpa-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:206) ~[spring-data-jpa-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:119) ~[spring-data-jpa-2.0.8.RELEASE.jar:2.0.8.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:56) ~[spring-data-jpa-2.0.8.RELEASE.jar:2.0.8.RELEASE] 

 

All source code is below. https://github.com/hkanali/gs-accessing-data-jpa


Affects: 2.0 Backlog, 2.0.9 (Kay SR9)

Reference URL: https://github.com/hkanali/gs-accessing-data-jpa

1 votes, 2 watchers

spring-projects-issues commented 5 years ago

alvinmeimoun commented

Migrated my project to Spring Boot 2.1.2, the issue seems to be fixed

schauder commented 3 years ago

Reported as fixed.