How to query on a subset of composite primary key

2019-08-23 20:43发布

This question already has an answer here:

How does Spring Data JPA support querying on a subset of a primary key? Or will I need to implement a custom repository method for this?

With classes like so:

@lombok.Data
@lombok.NoArgsConstructor
@lombok.AllArgsConstructor
@Entity
@Table(name = "my_entity")
class MyEntity {
    @EmbeddedId
    private Pk id;

    public Pk getId() {
        return id;
    }

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

}

@lombok.Data
@lombok.NoArgsConstructor
@lombok.AllArgsConstructor
@Embeddable
 class Pk implements Serializable {
    private Integer type;
    private String userId;


}

interface MyEntityRepository extends org.springframework.data.jpa.repository.JpaRepository<MyEntity, Pk> {

    java.util.Set<MyEntity> findAllByUserId(String userId);

}

On start up my Spring Boot application I am getting the error:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myEntityRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property user found for type MyEntity!
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:615)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:73)
    at com.myproject.backend.common.ServiceContext.start(ServiceContext.java:293)
    at com.myproject.run(AbstractServiceContainer.java:55)
    at com.myproject..run(AbstractServiceContainer.java:1)
    at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:42)
    at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:76)
    at io.dropwizard.cli.Cli.run(Cli.java:70)
    at io.dropwizard.Application.run(Application.java:72)
    at com.myproject..main(CombinedServiceContainer.java:106)
    Caused by: org.springframework.data.mapping.PropertyReferenceException: No property user found for type MyEntity!
    at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:359)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270)
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241)
    at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76)
    at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:213)
    at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:321)
    at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:301)
    at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:85)
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:60)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:91)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:168)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:69)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:320)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:169)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
    ... 18 more

Similar Questions

IdClass solution

This is similar to the question here and should have been answered there except the OP decided to go another route for the solution by using IdClass. Though that solution works this question is to show that there is a supported way without doing IdClass.

Query By Example Solution

This answer shows how to do it with Query By Example, which is great for more than one part of a composite key.

This question is different than the linked answers because the linked answers show how to solve the problem by writing a query method name. This question asks how to solve the problem by writing an SQL or HQL string in the query annotation.

1条回答
爷、活的狠高调
2楼-- · 2019-08-23 21:26

Simply define the query yourself:

@Query("select me from MyEntity me where me.id.userId = ?1")
java.util.Set<MyEntity> findAllByUserId(String userId);
查看更多
登录 后发表回答