简体   繁体   中英

JPA proper way to get DTO from database

I have database schema like this:

在此处输入图片说明

Now I want to write JPQL query or maybe use some other technology to get items from database with their types and info if item is borrowed right now and by who (just one borrower column instead of whole borrows list). I could use just normal query to get items with their types with EAGER loading and it could work but the problem is with borrows. How to get information about borrowing without taking whole list of borrows from database (or if I really have to do it how to designate borrower in a proper way)?

Item is borrowed if it has borrow with borrow_date NOT NULL and return_date NULL. My Item class looks like this:

public abstract class Item extends BaseEntity {

    private String isbn;
    private String title;
    private Integer pageNumber;

    @DateTimeFormat(iso = ISO.DATE)
    private LocalDate releaseDate;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "items_types", joinColumns = {
            @JoinColumn(name = "item_id", referencedColumnName = "id") }, inverseJoinColumns = {
                    @JoinColumn(name = "type_id", referencedColumnName = "id") })
    private Set<Type> types;

    @OneToMany(mappedBy = "item", cascade = { CascadeType.REMOVE })
    private List<Borrow> borrows;

I tried use JPQL with constructor using new POJO object like ItemDto, it lets me get current borrower but this time problem is with types, constructor can't take list of Type object. This is my query

select new com.test.library.dto.ItemDto(i.id, i.isbn,i.title, i.pageNumber, i.releaseDate, 
a.firstName, bb.lastName, i.types) from Item i LEFT JOIN i.borrows b ON (b.returnDate 
IS NULL) LEFT JOIN i.author a LEFT JOIN b.borrower bb 

i.types doesn't work, when I remove it, this constructor works fine, but I need item types to display it on my view, so what is the proper way to achieve this? I use spring-data-jpa + JPA 2.1.

JPA defines the constructor expression as follow :

constructor_expression ::=
         NEW constructor_name ( constructor_item {, constructor_item}* )
constructor_item ::=
         single_valued_path_expression |
         scalar_expression |
         aggregate_expression |
         identification_variable

It does not allow collection-value expression (ie i.types in your case ) in the constructor expression.

So , I think there are no standard JPA way to construct a DTO directly through query if your DTO contains a collection and you have to do this part of conversion manually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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