Montag, 4. Januar 2016

Jackson @JsonIdentityInfo, ObjectIdGenerators, bidirectional references

Recently we had a big issue with sending JSON in our Java Web App with Jackson. We had a pretty complex entity model and bidirectional references and used therefore @JsonIdentityInfo. @JsonManagedReference and @JsonBackReference didn't work because it was bidirectional.
At first we had the problem with duplicate properties:

{
    "links": [{
            "id": 2,
            "section1": {
                ...
            },
            "section2": {
                ...
            },
            "listLinkLabel": [{
                    "linkLabel": 1,
                    "linkLabel": "after"
                }]
        }, {
            "id": 5,
            "section1": {
                ...
            },
            "section2": {
                ...
            },
            "listLinkLabel": [{
                    "linkLabel": 2,
                    "linkLabel": "before"
                }, {
                    "linkLabel": 3,
                    "linkLabel": "overlap"
                }, 1]
        }, {
            "id": 3,
            "section1": {
                ...
            },
            "section2": {
                ...
            },
            "listLinkLabel": [3]
        }
}

As you can see linkLabel appears twice. This was because we used an IntSequenceGenerator on a String attribute:

@Entity
@JsonIdentityInfo(
        generator = ObjectIdGenerators.IntSequenceGenerator.class,
        property = "linkLabel")
public class LinkLabel implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    @Column(name = "LinkLabel")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private String linkLabel;

Then we had the problem that with the once encountered objects in the JSON are replaced by there ids with @JsonIdentityInfo:

{
    "objects": [{
            "id": 1,
            "otherObj": [{
                    "id": 1,
                    ...
                }, {
                    "id": 3,
                    ...
                }]
        },
            "id": 2,
            "otherObj": [1] <-- referencing otherObj with id 1
    ]
}


This is the Java Entity:


@Entity
@JsonIdentityInfo(
        generator = ObjectIdGenerators.IntSequenceGenerator.class,
        property = "linkLabel")
public class LinkLabel implements Serializable {
   //...
}

This behavior was a big problem on the JavaScript/ AngularJS client side. Fortunately we found the Jackson-Jsog plugin https://github.com/jsog/jsog-jackson. It can handle bidirectional references easily and can be used on client side as well.
So the code now looks like this:
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.voodoodyne.jackson.jsog.JSOGGenerator;

@Entity
@JsonIdentityInfo(generator=JSOGGenerator.class)
public class LinkLabel implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "LinkLabel")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private String linkLabel;

}

Simply add it in your pom.xml and on client side in your bower.json. It works like a charm!

Unity Pokemon

I had a bit time over the Christmas period and wanted to get familiar with Unity. So I decided to clone the Pokemon game with Unity. This is the result so far:



Link to the repository: https://bitbucket.org/JeanneDark/pokemonunity

Some time ago I tried the same with the Unreal Engine 4, but compared with Unity, it was much harder to create this game with UE4. This hardens the opinion that Unity is better with 2D games than UE4.