Using jersey-json POJO serialization feature on a jersey service function to return a JPA entity or a List<?> of that entity, how can I "tell" the serializer to dig deeper when serializing?
In other words, how do I tell the POJO Serializer to do a "Deep Serialization" (or specify the depth of each property) which returns a more detailed JSON with deeper data of the JPA object including it's mappings and relationships with other objects, those annotated with #ManyToOne and #OneToMany?
Without having to use that kind of solution: https://stackoverflow.com/a/10615608/230637
(My problem with the linked solution is the necessity to declare a bloated copy-constructor).
Thanks.
Related
Is there a way to programatically deserialize JSON to blaze-persistence entity view?
When I'm using standard jackson object mapper, and trying to do
mapper.readValue(serializedJSON, EntityViewImpl.class);
where serializedJSON is string representation (serialized from the same class of entity view), and EntityViewImpl.class is code-generated implementation of entity view interface, I'm getting an exception:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of (although at least one Creator exists): cannot deserialize from Object value (no delegate or property based Creator)
at [Source: (String) "{JSON representation of EntityView}"; line: 1, column: 2]
.
Same JSON correctly deserializes into entity that was basis for used entity view.
I noticed that there is a custom deserialization functionality as part of the blaze-persistance, although was not able to find any related documentation.
So any answer, eighther with standard jackson mapper or with custom blaze-persistence functionality would work for me.
You can use the Jackson integration which allows you to deserialize creatable/updatable entity views. There are integrations for JAX-RS and Spring WebMvc/WebFlux and even GraphQL though, so chances are, you don't have to do this plumbing yourself. If you share some more details like the entity view and the are where you want to do deserialization, I can give you a more extensive answer.
Previously in version 3 of Spring Data Elasticsearch, the Jackson mapper was used by default, but could be overridden to use the Metamodel object mapper, as documented here:
https://docs.spring.io/spring-data/elasticsearch/docs/3.2.0.RC1/reference/html/#elasticsearch.mapping.meta-model
I understand the Jackson mapper has been removed in version 4 and replaced with the Metamodel object mapper, as documented here:
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.mapping
But it appears the ability to override the object mapper was removed as well. Is there indeed no way to configure the Elasticsearch global object mapper to use Jackson (or any other mapper) again? It seems like a shame to lose the flexibility that option provided.
No. The MappingConverter is not only used and needed for converting an entity to and from JSON, but also for converting and mapping fieldnames, dateformats and other stuff for example when CriteriaQuerys are created or when search resukts like highlights are processed. There are man places in Spring Data Elasticsearch where the mapping information for an entity is needed and Jackson cannot be used there.
So in versions before 4.0 it was necessary to customize Jackson with jackson-annotations on the entity and the other stuff with different annotations, this has been consolidated.
What functionality do you need that the MappingConverter (implementation of the meta model mapper) does not offer in combination with custom converters?
Edit 05.12.2020:
valid point from the comments: It should be possible to define a FieldNamingStrategy for an entity. I created an issue for that.
I have an entity holding a collection (#OneToMany) which loads lazily. So far so good. If I load the entire list of entity objects (findAll()) I don't want the collection loaded at all. I don't access the collection therefore I assumed it will not be loaded before returning it from a REST endpoint, but it seems like Jackson accesses it when parsing it into JSON.
Currently I iterate over the entire entity list and set the collection to NULL. This seems like a very poor way of doing it, is there a way to ONLY manually load the collection with a specially prepared #Query and not load it automatically (either LAZY no EAGER) at all? Are #JsonViews the correct way to go or should I remove the #OneToMany annotation (I guess then I lose the mapping for the queries that actually do load the collection)? Any other suggestions?
Examplecode
#Entity
#Entity
public class Entity {
#OneToMany(targetEntity = Child.class)
private List<Child> children;
}
Jersey Resource
#GET
#Produces({MediaType.APPLICATION_JSON})
public List<Entity> getAllEntities() {
List<Entity> entities = entityService.findAll();
entities.forEach(e-> e.setChildren(null));
return entities ;
}
Repository = JpaRepository with default findAll() implementation.
thanks
Since you mentioned 'suggestion', I faced the same problem myself and I decided to implement custom DTOs to be sent in the API response. So I ommitted these collection fields and all other I did not want the json processors to touch.
I did implement my set of DTOs mirroring actual persisted entities, but there might be some other mappers to do the job
A few time ago, I asked a question about designing model classes for a REST API. There might be some information there useful for you.
Instead of reusing the same model classes for persistence and for the REST API, I've realized the best approach was creating different models. In some situations you don't want the persistence model to be the same as the model you use in your API. So, defining different models is the way to go.
And I chose MapStruct to map from one model to other.
I need to have a List of clasess that are Persistence Entities, I need have Entity Information, using Reflection API of JPA
I have the EntityManager, But I do not know if that is the way.
I want to do a generic logging for my Entities using a EntityListener. That works well, but I do not have the way to register the listener to all my entities.
Use the JPA2 MetaModel? It has assorted methods to see the entities (or managed types).
Set<javax.persistence.metamodel.EntityType<?>> entityTypes = entityManagerFactory.getMetamodel().getEntities();
for (javax.persistence.metamodel.EntityType entityType : entityTypes){
logger.info(entityType.getName());
logger.info(entityType.getJavaType().getCanonicalName());
logger.info("******************************");
}
Take a look at Configuration#getClassMappings()
Returns: Iterator of the entity mappings currently contained in the configuration.
JAXB works well until I need to do something like serialize beans for which I cannot modify the source. If the bean doesn't have a default constructor or if it refers to objects I want to mark transient then I'm stuck writing a separate bean which I can annotate and then manually copy the information over from the other bean.
For instance, I wanted to serialize exception objects, but found that the only way to do that was use a hack that required using com.sun.* classes.
So, what alternatives are there? What's the next most popular xml serializing api? It would be nice to be able to do things like:
Choose at serialization time whether to include certain fields in the result. (marking things transient when running the serializer).
Handle loops in the object graph by using references or something other than just dying.
Perhaps annotate an object so that in version 1 it serializes things in one way and in version 2 it serializes them in another. Then when serializing I just choose which version of the object ot serialize.
Have a way to generate XSDs from annotations on an object.
Basically I just want more flexibility than I currently have with JAXB.
Well the standard answer for wanting a uber configurable serialisation framework is xstream.
JAXB is a spec, so you can pick from different implementations. EclipseLink JAXB (MOXy) has extensions for what you are asking:
Externalized Metadata
Useful when dealing with classes for which you cannot annotate the source or to apply multiple mappings to an object model.
http://bdoughan.blogspot.com/2010/12/extending-jaxb-representing-annotations.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
XPath Based Mapping
For true meet-in-the-middle OXM mapping:
http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html
http://bdoughan.blogspot.com/2011/03/map-to-element-based-on-attribute-value.html
http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/MOXyExtensions
JPA Compatibility
Including support for bi-directional relationships.
http://bdoughan.blogspot.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA
Also look at JIBX. It's a good xml<->object mapper. My experience is though that if your objects have a somewhat funky relationships it's often easier to create a wrapper object that hides that complexity and then map that object with JIBX.
XStream is a popular XML serialisation library that claims to be able to serialize just about anyting, regardless of constructors or other problems (even deserialize final fields). Give it a try.
Requires no modifications to objects. Serializes internal fields, including private and final. Supports non-public and inner classes. Classes are not required to have default constructor.