Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

java - jpa constructor expressions with multiple SELECT NEW statements

Is there a way to have multiple SELECT NEW statements in a jpql query (Hibernate)?

This works for me:

@Query("SELECT NEW com.test.project.dto.ItemService(g,s,l,r) "
        +" FROM Item g, Service s, Service l , Service r"
        +" WHERE s.id = g.id" 
        +" AND s.location = l.name"
        +" AND s.serviceType = 'type'"
        +" AND l.serviceType = 'Location'"
        +" AND l.area = r.name" 
        +" AND r.serviceType = 'Region'")
public List<Item> getAllItemsWithServices();

I get the expected Result in my DTO.

@Component
public class ItemServiceDTO{

    private Item item;
    private Service serviceType;
    private Service serviceLocation;
    private Service serviceRegion;

    public ItemServiceDTO(item item, Service serviceType, Service serviceLocation, Service serviceRegion) {
        super();
        this.item = item;
        this.serviceType = serviceType;
        this.serviceLocation = serviceLocation;
        this.serviceRegion = serviceRegion;
    }

But what I want is to have a new instance of Language with its contructor.

For example like this:

 @Query("SELECT NEW com.test.project.dto.ItemService(g,s,l,r), new LanguageDTO()"
            +" FROM Item g, Service s, Service l , Service r"

Or in a subselect of ItemService

 @Query("SELECT NEW com.test.project.dto.ItemService(g,s,l,r, new LanguageDTO())"
                +" FROM Item g, Service s, Service l , Service r"

I also interested in using Map and List in my DTO Objects but I read thats not possible? Is that right?

My Spring boot application does start with errors while using the two examples.

At the end I want a Map of Map<List<Item>,Map<List<LanguageDTO>,List<ItemServiceDTO>>> map;

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Technically, by definition of JPQL select clause, it would allow multiple constructor expressions.

  • select_clause ::= SELECT [DISTINCT] select_expression {, select_expression}*
  • select_expression ::= single_valued_path_expression | aggregate_expression | identification_variable |
    OBJECT(identification_variable) | constructor_expression
  • constructor_expression ::= NEW constructor_name ( constructor_item {, constructor_item}* )
  • constructor_item ::= single_valued_path_expression | aggregate_expression
  • aggregate_expression ::= { AVG | MAX | MIN | SUM } ([DISTINCT] state_field_path_expression) | COUNT ([DISTINCT]
    identification_variable | state_field_path_expression |
    single_valued_association_path_expression)

Example:

SELECT NEW com.test.model.UserName(u.firstname, u.lastname), NEW com.test.model.UserEmail(u.email) FROM User u

However, I just discovered that Hibernate does not allow it. When I switched JPA provider from Hibernate to EclipseLink, it works. So, you may need to consult with your provider if such query syntax is allowed.

Take note however, that when using NEW operator, your constructor has to have arguments (at least one). So this expression won't work:

SELECT NEW LanguageDTO()

On your second question, whether it is possible to use List and Map, I'm quite confused how you would want to use these collections in your query. However, take note that it is not possible to have collection valued path expressions in your SELECT clause as per definition of the JPQL SELECT_CLAUSE.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...