JSON-B and lazy JPA entity
by Marek Kopecky
Hi,
what is the recommended way (best practice) to handle returning the JPA
entity with lazy loading from REST end-point with json-b? Example [1]
ends with 500 && LazyInitializationException.
AFAIK, there are several workarounds, like:
1. Do not return entity, use specific DTO
2. Iterate all collections in rest end-point (for example [2])
3. Use Jackson + jackson-datatype-hibernate module +
ContextResolver<ObjectMapper> implementation [3]. This hibernate
module is not a part of WF (so this is probably not recommended),
but it can be added to the deployment. This approach doesn't throw
LazyInitializationException, but this doesn't return lazy
collections as well.
4. Use JsonbTransient annotation. This approach doesn't throw
LazyInitializationException, but this doesn't return lazy
collections as well.
5. Convert object to string json in end-point (something like [5]).
End-point returns String.
6. ??? Some other workaround ???
Are there some correct solution or plan to implement correct solution?
If not, which workaround is recommended?
Marek
========================================
[1]
@Entity
public class User {
@OneToMany(mappedBy = "owner", fetch = FetchType.LAZY)
List<Task> tasks;
...
}
@GET
@Path("get/normal/{id}")
@Produces(MediaType.APPLICATION_JSON)
public User getByIdNormal(@PathParam("id") Long id) throws Exception {
return userDao.getUser(id);
}
========================================
[2]
@GET
@Path("get/iterate/{id}")
@Produces(MediaType.APPLICATION_JSON)
public User getByIdIterate(@PathParam("id") Long id) throws Exception {
return fixLazy(userDao.getUser(id));
}
private User fixLazy(User u) {
Iterator<Task> it = u.getTasks().iterator();
while (it.hasNext()) {
it.next();
}
return u;
}
========================================
[3]
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonDatatypeJacksonProducer implements
ContextResolver<ObjectMapper> {
private final ObjectMapper json;
public JacksonDatatypeJacksonProducer() throws Exception {
this.json = new ObjectMapper()
.findAndRegisterModules()
.registerModule(new Hibernate5Module());
}
@Override
public ObjectMapper getContext(Class<?> objectType) {
return json;
}
}
========================================
[5]
@GET
@Path("get/iterate/{id}")
public String getByIdConvertToString(@PathParam("id") Long id)
throws Exception {
return convertObjectToJsonString(userDao.getUser(id));
}
5 years, 8 months