如何使用 jpa 存储库查询多对一映射
Posted
技术标签:
【中文标题】如何使用 jpa 存储库查询多对一映射【英文标题】:how to query on many to one mapping with jpa repository 【发布时间】:2018-01-27 02:31:39 【问题描述】:我浏览了很多关于我的问题的堆栈,但我得到的答案很少在我的应用程序中不起作用。 我正在尝试根据由@OnetoMany 注释映射的父类中的字段来查询数据。
我的父类是NodeDetails:
@Entity
@Table(name = "tb_node_details")
public class NodeDetails implements Serializable
/**
*
*/
private static final long serialVersionUID = 3232846606798223969L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "instance_id", nullable = false)
private String instanceId;
@Column(name = "host_id")
private String hostId;
@Column(name = "host_type")
private String hostType;
@Column(name = "client_name")
private String clientName;
我有一个子类,它是 NodeAdapterKindDetails:
@Entity
@Table(name = "tb_node_adapter_kind_details")
public class NodeAdapterKindDetails implements Serializable
/**
*
*/
private static final long serialVersionUID = 6542657705062870675L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "adapter_kind", nullable = false)
private String adapterKind;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "node_id", nullable = false)
private NodeDetails nodeDetails;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "adapterKindDetails")
private Set<NodeAdapterInstanceDetails> adapterInstanceDetails = new HashSet<>();
它的子类是NodeAdapterInstanceDetails:
@Entity
@Table(name = "tb_node_adapter_instance_details")
public class NodeAdapterInstanceDetails
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "adapter_instance")
private String adapterInstance;
@Column(name = "active_status", columnDefinition = "varchar(20) default 'not active'")
private String activeStatus;
// TODO: change the timestamp from string to date... Check what is going
// wrong in the commented setTimeStamp method
@Column(name = "time_stamp")
private String timeStamp;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "adapter_kind_id", nullable = false)
private NodeAdapterKindDetails adapterKindDetails;
nodeAdapterInstance 类的 DAO:
@Repository(value="nodeAdapterInstanceDao")
public interface NodeAdapterInstanceDao extends JpaRepository<NodeAdapterInstanceDetails, Long>
@Query("select distinct n.adapterInstance from NodeAdapterInstanceDetails n where n.adapterKindDetails.nodeDetails.clientName = :client_name")
public List<String> getDistinctAdapterInstanceByClientName(@Param("client_name") String clientName);
@Query("select n from NodeAdapterInstanceDetails n where n.adapterInstance = :adapter_instance and n.adapterKindDetails.nodeDetails.clientName = :client_name")
public NodeAdapterInstanceDetails getLatestAdapterInstanceByAdapterInstanceAndClientName(@Param("adapter_instance") String adapterInstance, @Param("client_name") String clientName);
但是当我尝试运行 spring boot 时,在应用程序启动时我得到:
**
org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为“adapterKindParserServiceImpl”的 bean 时出错: 通过字段表示的不满足的依赖关系 'nodeAdapterInstanceDao';嵌套异常是 org.springframework.beans.factory.BeanCreationException:错误 创建名为“nodeAdapterInstanceDao”的bean:调用init 方法失败;嵌套异常是 org.springframework.data.mapping.PropertyReferenceException:否 找到类型 NodeAdapterInstanceDetails 的属性 clientName!
**
我是否对查询做错了什么,我该如何解决这个错误。 我们可以像这样使用 JPA 存储库,@query:
@Query("select n from NodeAdapterInstanceDetails n where n.adapterInstance = :adapter_instance and n.adapterKindDetails.nodeDetails.clientName = :client_name")
由于我在节点适配器实例类中没有客户端信息,我需要从我的层次结构中的最父节点获取它,即节点详细信息类。
这是我的服务:
@Service
public class AdapterKindParserServiceImpl implements NodeAdapterKindDetailsParserService
@Autowired
@Qualifier(value="nodeAdapterInstanceDao")
private NodeAdapterInstanceDao nodeAdapterInstanceDao;
private List<String> getDistinctAdapterInstances(String clientName)
return nodeAdapterInstanceDao.findDistinctAdapterInstanceByClientName(clientName);
我的完全例外:
org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为“adapterKindParserServiceImpl”的 bean 时出错: 通过字段表示的不满足的依赖关系 'nodeAdapterInstanceDao';嵌套异常是 org.springframework.beans.factory.BeanCreationException:错误 创建名为“nodeAdapterInstanceDao”的bean:调用init 方法失败;嵌套异常是 org.springframework.data.mapping.PropertyReferenceException:否 找到类型 NodeAdapterInstanceDetails 的属性 clientName!在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] 在 org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] 在 org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] 在 com.vmware.supernova.TopolizerApp.main(TopolizerApp.java:18) [classes/:na] 由以下原因引起: org.springframework.beans.factory.BeanCreationException:错误 创建名为“nodeAdapterInstanceDao”的bean:调用init 方法失败;嵌套异常是 org.springframework.data.mapping.PropertyReferenceException:否 找到类型 NodeAdapterInstanceDetails 的属性 clientName!在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] ... 19 常见 帧省略原因: org.springframework.data.mapping.PropertyReferenceException:否 找到类型 NodeAdapterInstanceDetails 的属性 clientName!在 org.springframework.data.mapping.PropertyPath.(PropertyPath.java:77) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:329) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:309) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:272) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.repository.query.parser.Part.(Part.java:76) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.repository.query.parser.PartTree$OrPart.(PartTree.java:247) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:398) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.repository.query.parser.PartTree$Predicate.(PartTree.java:378) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.repository.query.parser.PartTree.(PartTree.java:89) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.jpa.repository.query.PartTreeJpaQuery.(PartTreeJpaQuery.java:64) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] 在 org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] 在 org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:214) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] 在 org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:77) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] 在 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.(RepositoryFactorySupport.java:436) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:221) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:277) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:263) ~[spring-data-commons-1.13.6.RELEASE.jar:na] 在 org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:101) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] ... 29 常见 框架省略
请说明如何解决此异常。如果可能的话,请说出使用@OnetoOne、@OnetoMany 和@ManytoMany 查询的更好方法。
提前致谢
【问题讨论】:
【参考方案1】:像这样更正您的查询:
select distinct
n.adapterInstance
from
NodeAdapterInstanceDetails n
join n.adapterKindDetails ad
join ad.nodeDetails nd
where
nd.clientName = :client_name
select
n
from
NodeAdapterInstanceDetails n
join n.adapterKindDetails ad
join ad.nodeDetails nd
where
n.adapterInstance = :adapter_instance and
nd.clientName = :client_name
要获得使用已提交的链接实体的能力,您首先必须“加入”该实体。
更多信息:JPQL Language Reference
【讨论】:
@Query("select n from NodeAdapterInstanceDetails n join n.adapterKindDetails a join a.nodeDetails d where n.adapterInstance = :adapter_instance and d.clientName = :client_name") 我仍然遇到同样的异常 从上面的@query 中删除适配器连接,我这样写:@Query("select n from NodeAdapterInstanceDetails n join n.nodeDetails d where n.adapterInstance = :adapter_instance and d.clientName = :client_name ") 我还是同样的问题 @Niteshkumar 你不应该删除适配器'join' - 你的实体链接如下:InstanceDetails -> KindDetails -> NodeDetails,clientName
字段位于NodeDetails
。所以要到达这个字段,你必须使用两个连接。
@Niteshkumar Exception 说No property clientName found for type NodeAdapterInstanceDetails
- 所以请检查您的查询。在我的查询中clientName
在NodeDetails
..
是的,正如你所说,我已经使用了adapterkind 和nodedetail 的查询连接,查询在第一条评论中给出。如果我们检查我发布的具有 clientName 属性的 NodeDetails 类。因此,即使在从 adapterInstance-> adapterKind -> nodeDetails 进行连接之后,我也无法弄清楚为什么会显示异常 no property clientName found for type NodeAdapterInstanceDetails以上是关于如何使用 jpa 存储库查询多对一映射的主要内容,如果未能解决你的问题,请参考以下文章