Best way of handling Jackson bi-directional references - jackson

I'm trying to build rest APIs for our core components using Jackson, and I had issues with some of the objects getting this exception:
javax.ws.rs.ProcessingException: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError)
After searching I came out to know about several ways how to solve it.
e.g.
https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
and I used the #JsonIdentityInfo which is working fine for me, but the question is WHAT IS THE BETTER WAY TO DO IT?
In this post:
Infinite Recursion with Jackson JSON and Hibernate JPA issue
There is a claim that need to use the #JsonIdentityInfo in caution cause it can cause problems:
In this case you've got to be careful, since you could need to read your object's attributes more than once (for example in a products list with more products that share the same seller), and this annotation prevents you to do so. I suggest to always take a look at firebug logs to check the Json response and see what's going on in your code.
I reached this article as well: http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html
#JsonIdentityInfo
I understood that #JsonIdentityInfo is newer approach in Jackson 2.
Advantage that it requires minimum code change (just to put this annotation in the problematic Object Model and no need to handle it from the other side.
A drawback is explained
#JsonIgnoreProperties
It requires to change more classes rather than just annotating the base one, and I'm not sure how it will will work if I have more than one class inheriting from that object model.

Related

FileHelper attributes limitied to fields/members only

I use the FieldQuoted attribute in my form class. I noticed that I cannot put this attribute on properties. It only allows it on members/fields. Is there a reason for this? Can this be expanded to allow for properties?
Reason I ask is that I use this class in other places that are property friendly but not member friendly at all (e.g. MVC model binder).
According to Allow Properties instead of fields #67
Yes the library started with fields in 2004 mostly because if you
support properties you must to ensure that are writable, can throw
errors, can slow down assignment with custom code, also the reflection
of .net 1.1 were incredible slow and dynamic code generation for
fields was easy to implement
Later for backward compatibility and lazyness I didn't support
properties, now autoproperties work better thanks to work in this PR
#170
But we must to do the effort and support full properties and try to
make a little impact in the previous code to avoid weird errors, maybe
with new record classes
There seem to have been some changes made against Autoproperties full support #170 but this hasn't been included in the release yet. It only seems to be available on the master branch.
I will be merging this but later I will change the way it works to
avoid use of both autoproperties and fields and also to allow
properties in the general way, but your implementation make the use of
autoproperties a simple task
If you're not happy with using that, I would suggest just creating a separate class for the import/export to mirror your existing class but using fields, as suggested by the accepted answer to Formatting properties with FileHelper. Probably the safest bet for now until they get released.

Data binding without a ViewModel

I am doing something I have never tried before. I am trying to create dynamic UI and bind it to a dynamic model. In other words, my web service is going to send back a small metadata description of my UI and the raw data to bind to it. Therefore, at build time, I don't know what UI I will be constructing and I don't know what my model will be. Binding them together seems VERY difficult if not impossible.
Mvx allows me to bind UI directly to a model WITHOUT it being an MvxViewModel. However, if I bind directly to the Model returned by the web service, I lose the ability to RaisePropertyChanged() since that only comes from MvxViewModel.
Normally, I would write a ViewModel that wraps the Model and have all the wrapped setters call RaisePropertyChanged(). However, in this case, my model is dynamic so I can't wrap it with a ViewModel at compile time since I don't know what it is until runtime.
Is there some cool trick I can use to construct a ViewModel that can wrap any C# model class and send out property changed events without knowing what properties the model class has until runtime?
I just discovered the DLR and the DynamicObject which seems to be perfect, but due to Apple restrictions, it will not work on Xamarin.iOS.
Without teasing DynamicObject into life on iOS, the main approaches that think of are:
You could change your webservice generation code so that it produces INotifyPropertyChanged - I've used libraries that do this - e.g. http://stacky.codeplex.com/SourceControl/latest#trunk/source/Stacky/Entities/Answer.cs - and if you can't change the webservice code generation itself, you might still be able to wrap or pervert the generated code using some kind of t4 or other templating trick.
You could investigate some kind of code that maps the web service objects to some kind of observable collection (Kiliman has suggested this in comments)
You could look at some kind of valueconverter (or maybe valuecombiner) which does the binding - I can fairly easily imagine a valueconverter which takes a wrapped model object and a string parameter (the property name) and which uses those two together (with some reflection) to work out what to do. I'm not as sure how this one would work with nested model objects... but even that could be possible...
You could look at some kind of custom binding extension for MvvmCross. This isn't as scary as it sounds, but does require some reflection trickery - to understand what might be involved take a look at the FieldBinding plugin - https://github.com/MvvmCross/MvvmCross-Plugins/tree/master/FieldBinding
During the actual data-binding process, the plugin will be called via IMvxSourceBindingFactoryExtension - that would be your opportunity to hook into some other custom change event (rather than INotifyPropertyChanged). It might take a little experimentation to get this right... especially if you have nested objects (which then require "chaining" within the binding)... but I think it should be possible to produce something this way.
I am not sure if what I finalized on supports all possible functionality, but so far, it seems to satisfy everything that I need.
I really liked the idea of writing my own IMvxSourceBindingFactoryExtension. However, in investigating how to do that, I started playing with the functionality that already exists within MvvmCross. I already knew that MvvmCross would honor an ObservableCollection. What I didn't know was that I could use [] in my binding expressions AND that not only would integer indexers work, but also string indexers on a Dictionary. I discovered that MvvmCross sample code already has an implementation of ObservableDictionary within its GIT repo. It turns out, that is all that I needed to solve my problem.
So my model contains static properties AND an ObservableDictionary<string,object> of dynamic properties where the key is the name of the dynamic property and the value is the value of the property.
My ViewModel wraps this model class to send out PropertyChanged notifications on the static properties. Since the Dictionary of dynamic properties is observable, MvvmCross already handles changes to members of that dictionary, including 2-way.
The final issue is how to bind to it in my binding expression. That is where the [] comes in. If my ObservableDictionary property name is called UserValues and it contains a value at key user1, then I can 2-way bind to it by using: UserValues[user1] and everything seems to work perfectly.
One issue I see is that I am now requiring my dynamic data source to return an ObservableDictionary to me instead of just a Dictionary. Is that asking too much?

Why and when must we need to add "[Serializable]" attribute?

1) Besides for serialization from an object into a file/memory…… When must we add "[Serializable]" attribute?
2) Why must we add that? Why cannot we directly save the object into some known formation to the .NET library?
3) How can I tell in what sitatuations we must add this attribute? In what conditions?
Many thanks!
1) Besides for serialization from an object into a file/memory…… When must we add "[Serializable]" attribute?
When you want to serialize it, or an object that contains it, directly or indirectly, to any other medium, e.g. a socket, RMI, ...
2) Why must we add that?
Because that's the way they designed it. Security reasons spring to mind: you really don't want a password to be serializable by default for example.
Why cannot we directly save the object into some known formation to the .NET library?
Firstly because Serialization preceded .NET by several years; secondly there are various other ways of accomplishing that, such as SOAP.
3) How can I tell in what situations we must add this attribute? In what conditions?
You're just re-asking the same question here, two more times. You certainly need to do it if you ever get a NotSerializableException naming the class and the exception didn't indicate an inadvertent serialization of something you didn't intend to serialize in the first place.

Does adding PetaPoco attributes to POCO's have any negative side effects?

Our current application uses a smart object style for working with the database. We are looking at the feasibility of moving to PetaPoco instead. Looking over the features I notice you can add attributes to make it easier to CRUD objects. Does adding these attributes have any negative side effects that I should be aware of?
Has anyone found a reason NOT to use these decorators?
Directly to the use of the POCO object instance itself? None.
At least not that I would be aware of. Jon Skeet should be able to provide more info because he knows compiler inner workings through and through, so he knows exactly what happens with this metadata after it's been compiled.
Other implications indirectly related to these
There are of course implications when accessing these declarative attributes, because they're read using reflection which is normally a slow process.
But there's nothing to worry here, because PetaPoco is a smart library and reads these only once then compiles & caches these things, so you only get penalized once then you get blazing performance afterwards. Because it uses compiled code.
Non-performance related implications
By putting attributes (any) on your classes/properties/methods you somehow bind your code to particular engine that will use this class, because they're directives for this particular engine to understand your code.
In case of PetaPoco attributes this means that your class can be used with PetaPoco but not with some other DAL (ie. EF) unless you add attributes of that one as well (EF Code First uses the very same approach with attributes).
The second implication is related to back-end database. In case you rename a table, column or any other part that is provided in your PetaPoco attribute as a constant magic string, you will subsequently have to change this string as well. This just means that you have to be thorough when doing database changes...
One downside is that it breaks the separation between the "domain" layer and the "data" layer, since it introduces the PetaPoco file (which contains data logic) to domain classes that should really not have any knowledge or dependency on the data layer.
If you're doing a single-project MVC app or something then it's okay to just use the Models directory for both, but for non-trivial and separated apps you'll have to have two PetaPoco files or play around with abstracting portions of the file in order to annotate your models without making them "know too much" about the underlying data, or else have you specify the table and/or primary key name all over the place.

Jackson serialization should ignore already included objects

So this seems like a fairly simple answer to a common problem: Infinite loop detected in Jackosn. If, when serializing an object tree, Jackson comes upon an object it has already serialized why doesn't it just ignore it? Is there a way to do this in Jackson, or has someone created something similar?
Why all this mucking around with JsonManagedReference/JsonBackReference, which is completely insufficent if you start serializing child objects (which need a reference to the parent) some of the time and you are serializing parent objects some of the time (which obviously doesn't want the child to refer back to itself)?
It seems like now I have to create custom views that take into account every type of circular reference and use case possible which in any non-trivial ORM is a huge task.
EDIT (October 2012)
Jackson 2.x actual now DOES support identity information handling with #JsonIdentityInfo annotation! So the original answer is bit out of date...
OBSOLETE
Jackson does not support handling of object identity: this is a non-trivial task not so because of identifying shared objects which can be done by traversing object graph (incurring some overhead), but rather in figuring out how to include identity information; which ids to use and how. This in turn is somewhat similar to inclusion of type information, but now adds second dimension of extra wrapping to handle.
Doing this has been requested before, and some thought has gone into figuring out how to do it, but ratio of effort to benefit (i.e. number of requests, how badly it is needed) has been higher than adding other features.
So your best bet is to use wrapper objects and implement this manually, or have a look at XStream which can solve this (when enabled; it adds significant overhead in time) and also has JSON output mode using Jettison.
Implementing this manually for your use case is bit easier than solving the general case: you could start with BeanSerializerModifier to add wrapper handler that can keep track of object identities, and know what to serialize instead as object id.