【问题标题】:How to query on a subset of composite primary key with @EmbeddedId or @Id key object (without using IdClass)? [duplicate]如何使用@EmbeddedId 或@Id 键对象(不使用IdClass)查询复合主键的子集? [复制]
【发布时间】:2017-10-12 14:05:17
【问题描述】:

Spring Data JPA 如何支持查询主键的子集?或者我是否需要为此实现自定义存储库方法

像这样的类:

@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);

}

在启动我的 Spring Boot 应用程序时出现错误:

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

类似问题

IdClass 解决方案

这类似于问题here 并且应该在那里得到回答,除非 OP 决定使用 IdClass 为解决方案走另一条路线。尽管该解决方案有效,但这个问题是为了表明有一种无需执行 IdClass 的受支持方式。

通过示例解决方案查询

This answer 展示了如何使用 Query By Example 来做到这一点,这对于复合键的多个部分非常有用。

此问题与链接答案不同,因为链接答案显示了如何通过编写查询方法名称来解决问题。本题是问如何在查询注解中写一个SQL或者HQL字符串来解决这个问题。

【问题讨论】:

    标签: hibernate spring-data spring-data-jpa


    【解决方案1】:

    只需自己定义查询:

    @Query("select me from MyEntity me where me.id.userId = ?1")
    java.util.Set<MyEntity> findAllByUserId(String userId);
    

    【讨论】:

    • 有一种方法可以在不定义查询的情况下做到这一点。您可以将您的方法命名为“findByIdUserId”并且它可以工作。它比在您不需要时使用查询更干净。
    • 在你看来是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多