Deserializing json and resolving JPA entities - json

I have two entities X and Y with the relation #ManyToMany. X has a list of Y's, let's call it yList. Both X and Y has other class members as well (they are not important).
I am using Hibernate as JPA provider, and jackson-databind / jackson-annotations for things like serialization and deserialization.
Now, the following json is received from the client. It has all the fields of X, but only a list of id's for Y. As a concrete example, X could be Person and Y could be Country. And the many-to-many relation captures which countries have been visited by whom.
{
name: 'Bob Dylan',
age: '74',
visitedCountryIds: ['45', '23', '85']
}
When deserializing this json, I want to populate all the fields of the entity X, including yList, such that the elements of yList are resolved by looking up these entities in the database.
My idea so far is to deserialize yList by writing a custom subclass of JsonDeserializer, and have it perform the lookup by id.
Is this a reasonable approach?

You could use #JsonCreator (as already suggested by Uri Shalit) or just a setter method for your property in which you would do necessary lookups from the database.
However, if you have many entities (and associations) for which you want to do this, then this could be a repeated boilerplate code. Also, if implemented in entity classes directly, it would pollute them with database lookup code (readability, SRP, etc).
If you want some generic approach to this, then I think you are on a good way; custom deserializer is the place to implement it.
If I were to implement the generic approach, I would probably introduce a custom annotation which I would place on the association definition together with standard JPA annotations. For example:
#MyCustomJsonIds("visitedCountryIds")
#ManyToMany(...)
private List<Country> countries;
Then, in the deserializer, I would query for the presence of those annotations to dynamically determine what needs to be looked up from the database.

Another option is to create a constructor that that accepts those parameters, annotate it with #JsonCreator and have the constructor perform the lookup from the database, this way you don't need to write a specific deserializer.

Related

Freemarker: find specific object in array of arrays

I have a complex many-to-many relationship defined. The cross-reference table is an entity, so I have Contact with a One-To-Many to ContactList, and List with a One-To-Many to Contact List. Contact List contains listID, contactID, and a few Booleans. The relationships seem to work well and on the backend I can get a list of contacts on a review list using the Spring-Data-Jpa findByContactListsIn(Set).
However, I am trying to build a list of contacts in Freemarker, and show whether they were in the current list.
Before I made an Entity out of ContactList, I had a standard Many-To-Many relationship between them, and I was able to do something like this in my .ftl:
<#if list.contacts?seq_contains(contact)>
But I needed to add some data to ContactList specifically, so I needed it to be more complicated. How can I do something similar now? I tried:
<#if list.contactLists?seq_contains(contact)
But of course that always returns false, because it is comparing two different entity types. Is there a way to find if a contact is in one of the contactList objects?
I suppose I could do some back-end trickery, but I am looking for a front-end solution to this.
Don't use ?seq_contains for finding generic object at all. It doesn't call Object.equals, instead it works like the == operator of the template language, which only allows comparing strings, numbers, booleans and dates/times, otherwise it gives you an error. Unfortunately it won't fail in your case, because POJO-s are also strings (and their string value is what toString() returns). This is an unfortunate legacy of the stock ObjectWrapper (scheduled to be fixed in FM3); not even a quirk in the template language. Ideally you get an error there. Instead, now it silently compares the return value of the toString()-s...
Your data-model should already contain what the template should actually display. FTL is not a programming language, so if you try to extract that from the data-model in it, it will be a pain. But, that the data-model contains that data can also mean that some objects in the data-model have methods that extract the data you need. As a last resort, you can add objects that just contain helper methods.
Update: Returning to ?seq_contains, if you need the Java semantics and list is a Java Collection, you can just use the Java API: list?api.contains(contact).

JAX-RS + JPA, how to update/merge only a subset of an Entity's fields?

Suppose I have the following Entity:
#Entity
#XmlRootElement
#XmlAccessorType( XmlAccessType.FIELD)
public class MyEntity {
#Id
#GeneratedValue
private long id;
private boolean field1;
private boolean field2;
private boolean field3;
}
Suppose I have a REST Web Service that allows clients to POST partial or complete updates to a MyEntity resource. Perhaps the method signature looks something like this:
#POST
#Path("{id}")
public Response postMyEntity(#PathParam("id") long id, MyEntity myEntity)
Below is the JSON that a client might use to update only "field2" of MyEntity with id 101:
{
"id": 101
"field2": true
}
If JPA knew that only field2 was set during the de-serialization process then I'd love to persist this change with code as simple as:
entityManager.merge(myEntity);
However, this operation updates field1, field2, and field3.
How do people typically ensure that only the fields explicitly specified in the JSON/XML from the REST request are updated in the database? I've read about people using DTOs in their web service (as opposed to the Entities themselves) and manually figuring out what fields need to be set on the corresponding Entity...however, this use case seems so common that I'm surprised it would require a DIY approach.
Perhaps there is a better solution out there but I settled on forcing my REST service to produce and consume DTOs instead of Entities. My DTO classes never use primitives (Integer instead of int), which ensures that if a client omits a JSON/XML attribute then the corresponding DTO field will be null.
When I receive a POST to update a resource I:
Get the corresponding Entity from the database.
Copy all of the non-null fields from the DTO to the Entity.
Use JPA's merge functionality to update the database.
When I receive a GET for a resource I:
Get the Entity from the database.
Copy all of the fields from the Entity to a new DTO.
Return the DTO to the client.
Setting this up was tedious because it required me to:
Create a bunch of DTO classes that are nearly identical to the corresponding Entity classes.
Write logic to convert between DTOs and Entities.
Maintain this mess going forward.
Instead of using DTOs I suppose I could have eliminated primitives from my Entity classes and added not-null constraints to those fields. However, I read in several places that it is a "bad idea" to expose your Entity classes directly to REST clients. So I went ahead with the DTO solution even though I'm not the biggest fan of it.

Entity Framework Serialize entity to json with included related entities

I have a User entity with too many relations to other entities in the system. And I am using AngularJs and want to serialize the User entity to json with only the included entities.
Here is my select statement:
var users = unc.Users.Include("Profile").ToList();
when serializing this to json it will always result into
The operation cannot be completed because the DbContext has been disposed
I used to solve this problem by just selecting every column I need in my view like this:
var users = unc.Users.Select(x => new { x.Id ,x.Username,Role=x.Role.Name,x.Email,x.Profile.Name,x.UpdatedAt,x.CreatedAt}).ToList();
but this is too hard and much code to write. I am looking for the ideal or a better solution.
Thanks
I'v found a decent solution here.
https://efjson.codeplex.com/
This will serialize your entity without including related entities unless you wanted to include those entities. This will avoid entering into circular loops caused by entities calling each other back through reversed attributes.
Also serializing related entities you want will make it easy to serialize an entity and through the JSON back to scripts like AngularJs.
Hope this will make other people happy too :)

Casting objects created in LINQ to SQL to a single master object

I have an interesting problem to solve that would be helped by successfully casting objects created by LINQ to SQL into a single master object that I could pass around. Here is the scenario at a high level.
I have a number of stored procedures that fetch data and then all return the exact same columns. The params into the procs and the logic vary greatly, so a single proc will not work. Then Linq creates a strongly typed object which is used throughout my application as parameter and return values.
I am using these strongly typed objects as noted above as parameters and return values in a series of filters used to analyze stocks. My client would like to change the order the order of the filters. The issue is that each succeeding filter will only work on what passed the last filter.
Currently I am hard coding my parameters, and if I could create a master object that I could cast any of these Linq objects to, I could then always pass and return the master object.
I have read the materials available on the internet about casting between different types such as static to anonymous types or a list of integers and an array list containing objects representing integers, but I need to actually cast one object into another.
What general direction would I take to solve this problem of converting strongly typed objects generated by linq that are exactly the same into a single master object?
Thank you for any of your thoughts.
If all your linq objects have the same fields, you could have them implement an interface defined with those common fields. Then the calls to your filter methods can depend on an interface rather than a specific implementation. In other words, the parameters in the filter methods will be of the interface type rather than a linq class type.
e.g.: Where ICommonFields is an interface you define with all the common fields in each l2s class -
public class Filterer
{
public ICommonFields filterStuff(ICommonFields x)
{
//do stuff
}
}
or -
public class Filterer
{
public T filterStuff<T>(T x)
where T: class, ICommonFields, new()
{
//do stuff
}
}
I'd prefer the generic version, as T becomes the actual type rather than a reference through an interface - linq-to-sql has issues when using a type through an interface with query expressions.
Edit: sorry, it was late when i first wrote this response (likely excuse! :). Fixed my obvious mistake with the example code :)
Although there might be a way to do this with casting, I'm going to offer you a quick and dirty solution - and I'm assuming that your resultant objects are collection-based:
Given that all of your child objects
all share the same columns, go ahead
and pick one of them to act as your
master object - then simply iterate
through the rows of your other LINQ
objects and add them to the collection
of your master object. If your
resultant object is a strongly typed
data table, then all you'd do is Add
to the .Rows collection.
Additionally, you might be able to just add the elements retrieved some subsequent LINQ queries directly to your master object depending upon how you write your SELECT causes in LINQ.

LINQ to SQL strings to enums

LINQ to SQL allows table mappings to automatically convert back and forth to Enums by specifying the type for the column - this works for strings or integers.
Is there a way to make the conversion case insensitive or add a custom mapping class or extenstion method into the mix so that I can specify what the string should look like in more detail.
Reasons for doing so might be in order to supply a nicer naming convention inside some new funky C# code in a system where the data schema is already set (and is being relied upon by some legacy apps) so the actual text in the database can't be changed.
You can always add a partial class with the same name as your LinqToSql class, and then define your own parameters and functions. These will then be accessible as object parameters and methods for this object, the same way as the auto-generated LinqToSql methods are accessible.
Example: You have a LinqToSql class named Car which maps to the Car table in the DB. You can then add a file to App_Code with the following code in it:
public partial class Car {
// Add properties and methods to extend the functionality of Car
}
I am not sure if this totally meets your requirement of changing the way that Enums are mapped into a column. However, you could add a parameter where the get/set properties will work to map the enums that you need while keeping things case-insensitive.