首页 > 解决方案 > 将本机查询映射到 SpringBoot 中的非实体类

问题描述

我还是 Jpa 和 Springboot 的新手,所以我正在开发一个应用程序,我想从 2 个表中检索特定列,下面是 SearchResponse 类的代码片段。假设将查询结果映射到 SearchResponse

package com.nayiroom.model.customs;



import javax.persistence.*;
import java.util.UUID;


@SqlResultSetMapping(
        name = "SearchResponseMap",
        classes = @ConstructorResult (
                        targetClass = SearchResponse.class,
                        columns = {
                                @ColumnResult(name="rent",type = Double.class),
                                @ColumnResult(name="deposit",type = Double.class),
                                @ColumnResult(name="city",type = String.class),
                                @ColumnResult(name="room_id",type = UUID.class)
                        }
                        )
)
@NamedNativeQuery(
        name = "SearchResponseQuery.SearchResults",
        query="select rent, deposit, city, suburb, room_id\n" +
                "from room\n" +
                "join address\n" +
                "on  address.address_id = room.address_address_id",
        resultSetMapping = "SearchResponseMap")

public class SearchResponse {

    private double rent;
    private  double deposit;
    private String city;
    private  UUID room_id;

    public SearchResponse(double rent, double deposit, String city, UUID room_id) {
        this.rent = rent;
        this.deposit = deposit;
        this.city = city;
        this.room_id = room_id;
    }

    public double getRent() {
        return rent;
    }

    public void setRent(double rent) {
        this.rent = rent;
    }

    public double getDeposit() {
        return deposit;
    }

    public void setDeposit(double deposit) {
        this.deposit = deposit;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public UUID getRoom_id() {
        return room_id;
    }

    public void setRoom_id(UUID room_id) {
        this.room_id = room_id;
    }
}

房间存储库,

@Repository
public interface RoomResponseRepository extends JpaRepository<SearchResponse,Long> {


    @Query(name = "SearchResponseQuery.SearchResults")
    List<SearchResponse> SearchResults();

}

但是当我尝试运行应用程序时出现此错误

> Task :Application.main()

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.6.RELEASE)

2020-05-17 21:06:44.295  INFO 5318 --- [           main] com.nayiroom.Application                 : Starting Application on mdu-ThinkPad-L490 with PID 5318 (/home/mdu/Desktop/nayiroom mvp/build/classes/java/main started by mdu in /home/mdu/Desktop/nayiroom mvp)
2020-05-17 21:06:44.299  INFO 5318 --- [           main] com.nayiroom.Application                 : No active profile set, falling back to default profiles: default
2020-05-17 21:06:44.888  INFO 5318 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2020-05-17 21:06:44.955  INFO 5318 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 61ms. Found 2 JPA repository interfaces.
2020-05-17 21:06:45.460  INFO 5318 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 9090 (http)
2020-05-17 21:06:45.470  INFO 5318 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-05-17 21:06:45.470  INFO 5318 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.33]
2020-05-17 21:06:45.547  INFO 5318 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-05-17 21:06:45.547  INFO 5318 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1199 ms
2020-05-17 21:06:45.701  INFO 5318 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2020-05-17 21:06:45.753  INFO 5318 --- [           main] com.zaxxer.hikari.pool.PoolBase          : HikariPool-1 - Driver does not support get/set network timeout for connections. (Method org.postgresql.jdbc42.Jdbc42Connection.getNetworkTimeout() is not yet implemented.)
2020-05-17 21:06:45.770  INFO 5318 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2020-05-17 21:06:45.813  INFO 5318 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2020-05-17 21:06:45.857  INFO 5318 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.12.Final
2020-05-17 21:06:46.009  INFO 5318 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2020-05-17 21:06:46.092  INFO 5318 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL95Dialect
2020-05-17 21:06:46.523  INFO 5318 --- [           main] org.hibernate.tuple.PojoInstantiator     : HHH000182: No default (no-argument) constructor for class: com.nayiroom.model.Address (class must be instantiated by Interceptor)
2020-05-17 21:06:46.668  INFO 5318 --- [           main] org.hibernate.tuple.PojoInstantiator     : HHH000182: No default (no-argument) constructor for class: com.nayiroom.model.Image (class must be instantiated by Interceptor)
2020-05-17 21:06:46.678  INFO 5318 --- [           main] org.hibernate.tuple.PojoInstantiator     : HHH000182: No default (no-argument) constructor for class: com.nayiroom.model.Room (class must be instantiated by Interceptor)
2020-05-17 21:06:46.689  INFO 5318 --- [           main] org.hibernate.tuple.PojoInstantiator     : HHH000182: No default (no-argument) constructor for class: com.nayiroom.model.User (class must be instantiated by Interceptor)
2020-05-17 21:06:46.825  INFO 5318 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2020-05-17 21:06:46.829  INFO 5318 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-05-17 21:06:46.980  WARN 5318 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'roomController': Unsatisfied dependency expressed through field 'roomResponseRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roomResponseRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.nayiroom.model.customs.SearchResponse
2020-05-17 21:06:46.980  INFO 5318 --- [           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-05-17 21:06:46.983  INFO 5318 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-05-17 21:06:46.991  INFO 5318 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2020-05-17 21:06:46.993  INFO 5318 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2020-05-17 21:06:47.006  INFO 5318 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-05-17 21:06:47.011 ERROR 5318 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'roomController': Unsatisfied dependency expressed through field 'roomResponseRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roomResponseRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.nayiroom.model.customs.SearchResponse
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:882) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at com.nayiroom.Application.main(Application.java:14) ~[main/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roomResponseRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.nayiroom.model.customs.SearchResponse
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at **org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roomResponseRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.nayiroom.model.customs.SearchResponse**

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1290) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1210) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    ... 19 common frames omitted
**Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.nayiroom.model.customs.SearchResponse
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.nayiroom.model.customs.SearchResponse**

    at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:582) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:85) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:74) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:211) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:161) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:144) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:69) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:312) ~[spring-data-commons-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297) ~[spring-data-commons-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:212) ~[spring-data-commons-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.util.Lazy.get(Lazy.java:94) ~[spring-data-commons-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300) ~[spring-data-commons-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:121) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    ... 29 common frames omitted


> Task :Application.main() FAILED

Execution failed for task ':Application.main()'.
> Process 'command '/usr/lib/jvm/java-11-openjdk-amd64/bin/java'' finished with non-zero exit value 1


标签: javaspringhibernatespring-bootjpa

解决方案


您只能在实体类上使用 @SqlResultSetMapping 和 @NamedNativeQuery。从 JpaRepository 扩展的 RoomResponseRepository 应该指向可能映射为 @Entity 的“房间”实体。您的 SearchResponse 类应该是 DTO 类。

@Repository
public interface RoomResponseRepository extends JpaRepository<Room,Long> {
    
    @Query(name = "SearchResponseQuery.SearchResults")
    List<SearchResponse> SearchResults();

}

推荐阅读