如何使用@EmbeddedId或@Id键对象查询复合主键的子集(不使用IdClass)? [英] How to query on a subset of composite primary key with @EmbeddedId or @Id key object (without using IdClass)?

查看:210
本文介绍了如何使用@EmbeddedId或@Id键对象查询复合主键的子集(不使用IdClass)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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;



$ b @ lombok.Data
@ lombok.NoArgsConstructor
@ lombok.AllArgsConstructor
@Embeddable
class Pk实现Serializable {
private Integer类型;
private String userId;


}

接口MyEntityRepository扩展org.springframework.data.jpa.repository.JpaRepository< MyEntity,Pk> {

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

$ b $ / code>

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

 线程main中的异常org.springframework.beans.factory.BeanCreationException:创建名为'myEntityRepository'的bean时出错:调用init方法失败;嵌套的异常是org.springframework.data.mapping.PropertyReferenceException:找不到类型为MyEntity的属性用户!在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512)

在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(CombinedSe rviceContainer.java:106)
导致:org.springframework.data.mapping.PropertyReferenceException:找不到类型为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)
位于org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241)
位于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.Rep在org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210)
处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



< h2>类似的问题

IdClass解决方案



这与这里,应该在那里回答,除了OP决定通过使用IdClass去解决其他路线。虽然这个解决方案有效,但这个问题是为了证明没有IdClass的支持方式。



查询示例解决方案



此答案显示了如何使用Query By Example来完成此操作,这对于复合的多个部分很适用key。



这个问题与链接的答案不同,因为链接的答案显示了如何通过编写查询方法名称来解决问题。此问题询问如何通过在查询注释中编写SQL或HQL字符串来解决问题。 简单地自定义查询:

  @Query(从MyEntity me中选择我,其中me.id.userId =?1)
java .util.Set< myEntity所> findAllByUserId(String userId);


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.

解决方案

Simply define the query yourself:

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

这篇关于如何使用@EmbeddedId或@Id键对象查询复合主键的子集(不使用IdClass)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆