Creating DTOs Without Mapping with JPA and Java EE 📎
The Ping
class is a JPA entity and JSON-B DTO at the same time:
@Entity
@NamedQuery(name = "all", query = "SELECT p FROM Ping p")
public class Ping {
@Id
@GeneratedValue
public long id;
public String message;
public int age;
}
...the Ping
class can be directly read from a DB:
@Stateless
public class PingStore {
@PersistenceContext
EntityManager em;
public List<Ping> all() {
return this.em.createNamedQuery("all", Ping.class).getResultList();
}
}
...and exposed via JAX-RS:
@Path("ping")
public class PingResource {
@Inject
PingStore store;
@GET
public List<Ping> all() {
return this.store.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 com.airhacks.ping.entity.PingSlice(p.message) from Ping p", PingSlice.class).
getResultList();
}
exposed via JAX-RS again:
@GET
@Path("slices")
public List<PingSlice> allSlices() {
return this.store.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).
getResultList();
}
...exposed via JAX-RS:
@GET
@Path("strings")
public List<String> allStrings() {
return this.store.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: javaeemicro.services.