Creating DTOs Without Mapping with JPA and Java EE

The Ping class is a JPA entity and JSON-B DTO at the same time:

@NamedQuery(name = "all", query = "SELECT p FROM Ping p")
public class Ping {

    public long id;

    public String message;
    public int age;


...the Ping class can be directly read from a DB:

public class PingStore {

    EntityManager em;

    public List<Ping> all() {
        return this.em.createNamedQuery("all", Ping.class).getResultList();
...and exposed via JAX-RS:

public class PingResource {

    PingStore store;

    public List<Ping> all() {

curl -i http://localhost:8080/flight/resources/ping/ returns:

[{"age":0,"id":1,"message":"Enjoy Java EE 8!"},{"age":0,"id":2,"message":"Enjoy Java EE 8!"}]    

A dedicated DTO:

public class PingSlice {

    public long timestamp;
    public String flightName;

    public PingSlice(String flightName) {
        this.flightName = flightName;
        this.timestamp = System.currentTimeMillis();


can be directly mapped by the EntityManager:

public List<PingSlice> allSlices() {
        return this.em.createQuery("SELECT new from Ping p", PingSlice.class).

exposed via JAX-RS again:

public List<PingSlice> allSlices() {

and returned as JSON (curl -i http://localhost:8080/flight/resources/ping/slices):

[{"flightName":"Enjoy Java EE 8!","timestamp":1542797875539},{"flightName":"Enjoy Java EE 8!","timestamp":1542797875539}]    

Also primitive types like String, can be fetched with JPA:

public List<String> allStrings() {
        return this.em.createQuery("SELECT p.message from Ping p", String.class).
    } via JAX-RS:

public List<String> allStrings() {

and returned as JSON (curl -i http://localhost:8080/flight/resources/ping/strings)

["Enjoy Java EE 8!","Enjoy Java EE 8!"]

With Java EE JPA Entities can be used as DTOs first. A different "view" to the JPA entities can be implemented on-demand and without explicit mapping layers or mappers.

See you at Java EE Microservices. Is Munich's airport too far? Learn from home:

NEW workshops: MicroProfile with Quarkus and Micro Frontends with Web Components at MUC airport the podcast:

Stay in touch:


This works for simple cases but imagine the presentation you require alters the fetch graph. If you have sophisticated logic in the query and have multiple representations that all should be able to make use of the same query logic, this quickly runs into it's limits.
Nested structures are also not implementable with this approach. You'd need to do separate processing to be able to have collections in a DTO.
I suggest to use Blaze-Persistence Entity Views for real world cases ;)

Posted by Christian Beikov on November 21, 2018 at 01:10 PM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
Online Workshops
...the last 150 posts
...the last 10 comments