简体   繁体   English

spring boot jpa:从与表架构无关的jpa查询返回自定义对象

[英]spring boot jpa: return custom object from jpa query not related to table schema

Here is my configuration: Java: 1.8 Spring Boot :: v2.3.1.RELEASE这是我的配置:Java: 1.8 Spring Boot :: v2.3.1.RELEASE

I have following models/classes:我有以下模型/类:

Books: The Book class is as below.书籍:书籍类如下。 Please note this is not an entity related to table in DB, or can treat it as a data fetched from multiple tables with only required attributes.请注意,这不是与 DB 中的表相关的实体,也可以将其视为从多个表中提取的数据,仅具有必需的属性。 In short I won't have a table schema for following object.简而言之,我不会有以下对象的表模式。

package com.myservice.model;

public class Book {
    private long bookId;
    private String bookName;
    private String bookType;
    private String author;


    public Book(long bookId, String bookName, String bookType, String author) {
        this.bookId = bookId;
        this.bookName = bookName;
        this.bookType = bookType;
        this.author = author;
    }

    public long getBookId() {
        return bookId;
    }

    public void setBookId(long bookId) {
        this.bookId = bookId;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getBookType() {
        return bookType;
    }

    public void setBookType(String bookType) {
        this.bookType = bookType;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

}

Similar to the above, I have another class,与上面类似,我还有一个班级,

package com.myservice.model;

public class Business {

    private String businessName;
    private String businessType;
    private String owner;


    public Book(String businessName, String businessType, String owner) {
        this.businessName = businessName;
        this.bookType = bookType;
        this.owner = owner;
    }


    public String getBusinessName() {
        return businessName;
    }

    public void setBusinessName(String businessName) {
        this.businessName = businessName;
    }

    public String getBusinessType() {
        return businessType;
    }

    public void setBusinessType(String businessType) {
        this.businessType = businessType;
    }

    public String getOwner() {
        return owner;
    }

    public void setOwner(String owner) {
        this.owner = owner;
    }

}

I need the output as following object我需要作为以下对象的输出

import java.util.List;

public class Configuration {

    private List<Book> books;
    private List<Business> businesses;
    private List<String> authors;
    private List<String> owners;

    // Constructor and getters/setters omitted for brevity

}

So, I tried to have a repository所以,我试图拥有一个存储库

import com.myservice.model.Configuration;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ConfigurationRepository extends JpaRepository<Configuration, Long>, ConfigurationRepositoryCustom {

}

Custom interface自定义界面

import com.myservice.model.Configuration;

public interface ConfigurationRepositoryCustom {

    Configuration getConfigData();
}

Implementation:执行:

@Repository
@Transactional(readOnly = true)
public class ConfigurationRepositoryImpl implements ConfigurationRepositoryCustom {

    @PersistenceContext
    EntityManager entityManager;

    private List<Book> getBooks() {
        Query query = entityManager.createNativeQuery(
                "SELECT book_id, book, bookType, author FROM TABLE1 JOIN TABLE2 <Other criterias>"
                , Book.class
        );
        return query.getResultList();
    }

    private List<Business> getBusinesses() {
        List<Business> businesses = new ArrayList<>();
        businesses.add(new Business("ABC", "Constructions", "ABC PQR" ));
        businesses.add(new Business("XYZ", "Constructions", "PQR CCC" ));
        businesses.add(new Business("PQR", "Education", "ABC PQR" ));
        return businesses;
    }


    @Override
    public Configuration getConfigData() {
        List<Book> books = getBooks();
        List<Business> businesses = getBusinesses();
        
        List<String> authors = books.stream().map(Book::getAuthor).collect(Collectors.toList());
        List<String> owners = businesses.stream().map(Book::getOwner).collect(Collectors.toList());
        
        Configuration config = new Configuration(
                books,
                businesses,
                authors,
                owners
        );

        return config;
    }
}

Basically, if you see Configuration object is not in DB.基本上,如果您看到 Configuration 对象不在 DB 中。

When I start the app, it first threw this error:当我启动应用程序时,它首先抛出了这个错误:

Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.myservice.model.Configuration
    at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:582) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:85) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:75) ~[spring-data-jpa-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66) ~[spring-data-jpa-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:229) ~[spring-data-jpa-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:179) ~[spring-data-jpa-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:162) ~[spring-data-jpa-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:72) ~[spring-data-jpa-2.3.1.RELEASE.jar:2.3.1.RELEASE]

For the above, I added @Entity?对于上述,我添加了@Entity? annotation to my Configuration class对我的 Configuration 类的注释

Next, it threw the error :接下来,它抛出了错误:

Caused by: org.hibernate.AnnotationException: No identifier specified for entity: com.myservice.model.Configuration
    at org.hibernate.cfg.InheritanceState.determineDefaultAccessType(InheritanceState.java:266) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:211) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:781) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    

Now, my Configuration is not a table in DB, still I added the attribute "id"现在,我的配置不是数据库中的表,我仍然添加了属性“id”

@Id
@GeneratedValue
private long id;

Next, I get this error:接下来,我收到此错误:

Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: configuration, for columns: [org.hibernate.mapping.Column(books)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:499) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:466) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.mapping.Property.isValid(Property.java:227) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]

There is of course no such table in my DB.我的数据库中当然没有这样的表。

So, basically I am looking for a way to create a custom (Configuration here) object based on other objects (few from DB, few from other calls, etc) and this custom object is not in DB.因此,基本上我正在寻找一种基于其他对象(很少来自 DB,很少来自其他调用等)创建自定义(此处为配置)对象的方法,并且此自定义对象不在 DB 中。 So how to achieve the same?那么如何实现相同的呢?

You don't need this interface你不需要这个接口

public interface ConfigurationRepository extends JpaRepository<Configuration, Long>, ConfigurationRepositoryCustom {

}

Instead, use ConfigurationRepositoryCustom directly in your code, also you can use the name ConfigurationRepository (No need to suffix with custom).相反,直接在您的代码中使用ConfigurationRepositoryCustom ,您也可以使用名称ConfigurationRepository (无需以 custom 为后缀)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM