1

Is it possible to initialize multiple objects in a single query? I'm trying to introduce mapping of multiple attributes to corresponding DTOs, but am getting syntax error. The query is as follows:

em.createQuery("SELECT "
                                      + "new com.x.y.z(fte.attr1 "
                                      + "fte.attr2, fte.attr3),"

                                      + "new com.x.y.a(fet.attr4, fet.attr5,"
                                      + "fet.attr6, fet.attr7, fet.attr8, fet.attr9), "

                                      + "new com.x.y.b(fte.attr10,"
                                      + " fte.attr11, fte.attr12, fte.attr13, fte.attr14), "

                                      + "new com.x.y.c(fte.attr15, "
                                      + "fte.attr16, v.attr17, v.attr18) "

                                      + "FROM Table1 fte "
                                      + "LEFT JOIN Table2fet ON fte.attr1= fet.attr1 AND fte.attr1= fet.attr1"
                                      + "LEFT JOIN Table3 v ON v.attr1= fte.attr1"
                                      + "WHERE fte.attr1= :attr1 AND fte.attr1= :attr1",
                              Object[].class)
                .getResultStream()

however the JPA indicates a problem org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: , near line 1, column 115 which is resolved into new com.x.y.a location

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
user4165421
  • 131
  • 2
  • 11
  • According to the answer posted there, the JPA specification seems to allow it, but Hibernate does not – Jeroen Steenbeeke Jan 29 '21 at 07:53
  • Yup, the JPA standard does allow it and a quick switch to EclipseLink seems to work as well, but for whatever reason Hibernate doesn't allow for it – user4165421 Feb 02 '21 at 09:41

1 Answers1

0

Seems like Hibernate does not support this, but I think this is a perfect use case for Blaze-Persistence Entity Views.

I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model.

A DTO model could look like the following with Blaze-Persistence Entity-Views:

@EntityView(User.class)
public interface UserDto {
    @IdMapping
    Long getId();
    String getName();
    Set<RoleDto> getRoles();

    @EntityView(Role.class)
    interface RoleDto {
        @IdMapping
        Long getId();
        String getName();
    }
}

Querying is a matter of applying the entity view to a query, the simplest being just a query by id.

UserDto a = entityViewManager.find(entityManager, UserDto.class, id);

The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

The best thing about it is, it will only fetch the data that is actually needed.

Christian Beikov
  • 15,141
  • 2
  • 32
  • 58