Home how to query on many to one mapping with jpa repository
Reply: 1

how to query on many to one mapping with jpa repository

Nitesh kumar
1#
Nitesh kumar Published in 2017-08-18 11:54:47Z

I browsed lots of stack over flow for my issue, though I got few answer that's not working in my application. I am trying to query the data based on a field in the parent class which is mapped by @OnetoMany annotation.

My parent class is 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;

I have a child class which is 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<>();

And its child class is 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;

The DAO for the nodeAdapterInstance class:

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

}

But When I try to run the spring boot, at application startup I get:

**

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'adapterKindParserServiceImpl': Unsatisfied dependency expressed through field 'nodeAdapterInstanceDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nodeAdapterInstanceDao': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property clientName found for type NodeAdapterInstanceDetails!

**

Have I done anything wrong with the query, how could I resolve this error. Can we use JPA repository, @query like this:

@Query("select n from NodeAdapterInstanceDetails n where n.adapterInstance = :adapter_instance and n.adapterKindDetails.nodeDetails.clientName = :client_name")

Since I don't have the client Info in the Node Adapter Instance Class I need to take it from the parent most in my hierarchy which is Node Details class.

This is my service:

@Service
public class AdapterKindParserServiceImpl implements NodeAdapterKindDetailsParserService {
    @Autowired
    @Qualifier(value="nodeAdapterInstanceDao")
    private NodeAdapterInstanceDao nodeAdapterInstanceDao;
    private List<String> getDistinctAdapterInstances(String clientName) {
        return nodeAdapterInstanceDao.findDistinctAdapterInstanceByClientName(clientName);
    }
}

my complete exception:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'adapterKindParserServiceImpl': Unsatisfied dependency expressed through field 'nodeAdapterInstanceDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nodeAdapterInstanceDao': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property clientName found for type NodeAdapterInstanceDetails! at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at com.vmware.supernova.TopolizerApp.main(TopolizerApp.java:18) [classes/:na] Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nodeAdapterInstanceDao': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property clientName found for type NodeAdapterInstanceDetails! at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] ... 19 common frames omitted Caused by: org.springframework.data.mapping.PropertyReferenceException: No property clientName found for type NodeAdapterInstanceDetails! at org.springframework.data.mapping.PropertyPath.(PropertyPath.java:77) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:329) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:309) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:272) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.repository.query.parser.Part.(Part.java:76) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.repository.query.parser.PartTree$OrPart.(PartTree.java:247) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:398) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.repository.query.parser.PartTree$Predicate.(PartTree.java:378) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.repository.query.parser.PartTree.(PartTree.java:89) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.(PartTreeJpaQuery.java:64) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:214) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:77) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.(RepositoryFactorySupport.java:436) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:221) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:277) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:263) ~[spring-data-commons-1.13.6.RELEASE.jar:na] at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:101) ~[spring-data-jpa-1.11.6.RELEASE.jar:na] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE] ... 29 common frames omitted

Kindly say how to resolve this exception. And if possible say what could be a better way to use the queries for @OnetoOne, @OnetoMany and @ManytoMany.

Thanks in advance

Cepr0
2#
Cepr0 Reply to 2017-08-18 12:13:54Z

Correct your query like this:

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

To get ability to use the linked entity filed you first have to 'join' this entity.

More info: JPQL Language Reference

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.324012 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO