Agradeceríamos tu ayuda para compartir nuestras crónicas con relación a las ciencias informáticas.
Solución:
Tiene tantas opciones para mapear su proyección a un conjunto de resultados DTO:
Proyecciones DTO usando Tuple y JPQL
List postDTOs = entityManager.createQuery("""
select
p.id as id,
p.title as title
from Post p
where p.createdOn > :fromTimestamp
""", Tuple.class)
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of(2016, 1, 1, 0, 0, 0)
.toInstant(ZoneOffset.UTC )))
.getResultList();
assertFalse(postDTOs.isEmpty());
Tuple postDTO = postDTOs.get(0);
assertEquals(
1L,
postDTO.get("id")
);
Proyecciones DTO utilizando una expresión de constructor y JPQL
List postDTOs = entityManager.createQuery("""
select new com.vladmihalcea.book.hpjp.hibernate.query.dto.projection.jpa.PostDTO(
p.id,
p.title
)
from Post p
where p.createdOn > :fromTimestamp
""", PostDTO.class)
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
.toInstant( ZoneOffset.UTC ) ))
.getResultList();
También puede omitir el nombre del paquete DTO de la expresión del constructor JPA y hacer referencia al DTO por su nombre de clase Java simple (p. ej.,
PostDTO
).List
postDTOs = entityManager.createQuery(""" select new PostDTO( p.id, p.title ) from Post p where p.createdOn > :fromTimestamp
""", PostDTO.class)
.setParameter( "fromTimestamp", Timestamp.from( LocalDateTime.of( 2016, 1, 1, 0, 0, 0 ) .toInstant( ZoneOffset.UTC ) )) .getResultList();
Proyecciones DTO utilizando Tuple y consultas SQL nativas
Este está disponible en Hibernate 5.2.11, así que una razón más para actualizar.
List postDTOs = entityManager.createNativeQuery("""
SELECT
p.id AS id,
p.title AS title
FROM Post p
WHERE p.created_on > :fromTimestamp
""", Tuple.class)
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
.toInstant( ZoneOffset.UTC ) ))
.getResultList();
Proyecciones DTO utilizando un ConstructorResult
Si usamos el mismo PostDTO
tipo de clase introducido anteriormente, tenemos que proporcionar lo siguiente @SqlResultSetMapping
:
@NamedNativeQuery(
name = "PostDTO",
query = """
SELECT
p.id AS id,
p.title AS title
FROM Post p
WHERE p.created_on > :fromTimestamp
""",
resultSetMapping = "PostDTO"
)
@SqlResultSetMapping(
name = "PostDTO",
classes = @ConstructorResult(
targetClass = PostDTO.class,
columns =
@ColumnResult(name = "id"),
@ColumnResult(name = "title")
)
)
Ahora, la proyección de SQL denominada consulta nativa se ejecuta de la siguiente manera:
List postDTOs = entityManager.createNamedQuery("PostDTO")
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
.toInstant( ZoneOffset.UTC ) ))
.getResultList();
Proyecciones DTO usando ResultTransformer y JPQL
Esta vez, su DTO requiere tener los configuradores de las propiedades que necesita que Hibernate complete desde el JDBC subyacente. ResultSet
.
La proyección DTO tiene el siguiente aspecto:
List postDTOs = entityManager.createQuery("""
select
p.id as id,
p.title as title
from Post p
where p.createdOn > :fromTimestamp
""")
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 ).toInstant( ZoneOffset.UTC ) ))
.unwrap( org.hibernate.query.Query.class )
.setResultTransformer( Transformers.aliasToBean( PostDTO.class ) )
.getResultList();
Proyecciones DTO utilizando ResultTransformer y una consulta SQL nativa
List postDTOs = entityManager.createNativeQuery("""
select
p.id as "id",
p.title as "title"
from Post p
where p.created_on > :fromTimestamp
""")
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 ).toInstant( ZoneOffset.UTC ) ))
.unwrap( org.hibernate.query.NativeQuery.class )
.setResultTransformer( Transformers.aliasToBean( PostDTO.class ) )
.getResultList();
Puede usar ResultTransformer, que puede convertir propiedades de alias a bean (DTO). Para su uso, puede consultar los documentos de Hibernate aquí en la sección 13.1.5
Si sostienes algún recelo y disposición de avanzar nuestro sección eres capaz de realizar una anotación y con gusto lo analizaremos.