{"id":171,"date":"2024-01-16T00:28:44","date_gmt":"2024-01-15T23:28:44","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=171"},"modified":"2024-01-24T00:29:43","modified_gmt":"2024-01-23T23:29:43","slug":"bidirektionale-beziehungen-in-der-de-serialisierung-von-json-mit-jackson","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=171","title":{"rendered":"Bidirektionale Beziehungen in der (De-)Serialisierung von JSON mit Jackson"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\"><\/h1>\n\n\n\n<p>Die Verarbeitung von JSON-Daten ist in der heutigen Softwareentwicklung von entscheidender Bedeutung, da viele Anwendungen auf den Austausch von strukturierten Daten angewiesen sind. Die Jackson-Bibliothek, eine weit verbreitete Java-Bibliothek f\u00fcr die Verarbeitung von JSON, bietet leistungsstarke Mechanismen f\u00fcr die Serialisierung und Deserialisierung von Java-Objekten. In diesem Artikel werden wir uns auf bidirektionale Beziehungen zwischen Java-Klassen konzentrieren und wie Jackson diese Beziehungen effektiv handhabt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Einf\u00fchrung in Jackson<\/h2>\n\n\n\n<p>Jackson ist eine Java-Bibliothek, die es erm\u00f6glicht, JSON-Daten in Java-Objekte zu konvertieren und umgekehrt. Sie bietet eine einfache und flexible API, um Daten zwischen Java-Objekten und JSON zu \u00fcbertragen. Jackson verwendet Annotationen, um die Serialisierung und Deserialisierung von Java-Objekten zu steuern.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ Beispielklasse mit Jackson-Annotationen<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span> <\/span>{\n    @JsonProperty(<span class=\"hljs-string\">\"name\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String fullName;\n\n    @JsonProperty(<span class=\"hljs-string\">\"age\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> int age;\n\n    <span class=\"hljs-comment\">\/\/ Konstruktoren, Getter und Setter<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Im obigen Beispiel wird die <code>@JsonProperty<\/code>-Annotation verwendet, um die Zuordnung zwischen den Feldern der Java-Klasse und den Schl\u00fcsseln im JSON-Objekt festzulegen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bidirektionale Beziehungen verstehen<\/h2>\n\n\n\n<p>Bidirektionale Beziehungen treten auf, wenn zwei Klassen in einer Weise miteinander verbunden sind, dass eine Instanz einer Klasse eine Beziehung zu einer oder mehreren Instanzen der anderen Klasse hat, und umgekehrt. Dies kann in der Praxis h\u00e4ufig vorkommen, beispielsweise wenn wir eine <code>Person<\/code>-Klasse und eine <code>Address<\/code>-Klasse haben, wobei eine Person eine Adresse hat und eine Adresse einer oder mehreren Personen zugeordnet sein kann.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ Beispiel f\u00fcr bidirektionale Beziehung<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span> <\/span>{\n    @JsonProperty(<span class=\"hljs-string\">\"name\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String fullName;\n\n    @JsonProperty(<span class=\"hljs-string\">\"age\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> int age;\n\n    @JsonProperty(<span class=\"hljs-string\">\"address\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> Address address;\n\n    <span class=\"hljs-comment\">\/\/ Konstruktoren, Getter und Setter<\/span>\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Address<\/span> <\/span>{\n    @JsonProperty(<span class=\"hljs-string\">\"street\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String street;\n\n    @JsonProperty(<span class=\"hljs-string\">\"city\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String city;\n\n    @JsonProperty(<span class=\"hljs-string\">\"residents\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">List<\/span>&lt;Person&gt; residents;\n\n    <span class=\"hljs-comment\">\/\/ Konstruktoren, Getter und Setter<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel hat die <code>Person<\/code>-Klasse eine Referenz auf eine <code>Address<\/code>-Instanz, und die <code>Address<\/code>-Klasse hat eine Liste von <code>Person<\/code>-Instanzen als Bewohner. Dies ist eine bidirektionale Beziehung zwischen den Klassen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Herausforderungen bei der Serialisierung von bidirektionalen Beziehungen<\/h2>\n\n\n\n<p>Bei der Serialisierung von Objekten mit bidirektionalen Beziehungen k\u00f6nnen Schwierigkeiten auftreten. Wenn beide Klassen einfach so serialisiert werden, besteht das Risiko von Endlosschleifen oder redundanten Daten. Betrachten wir das obige Beispiel und wie Jackson damit umgeht.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ Beispiel f\u00fcr bidirektionale Beziehung<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span> <\/span>{\n    @JsonProperty(<span class=\"hljs-string\">\"name\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String fullName;\n\n    @JsonProperty(<span class=\"hljs-string\">\"age\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> int age;\n\n    @JsonProperty(<span class=\"hljs-string\">\"address\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> Address address;\n\n    <span class=\"hljs-comment\">\/\/ Konstruktoren, Getter und Setter<\/span>\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Address<\/span> <\/span>{\n    @JsonProperty(<span class=\"hljs-string\">\"street\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String street;\n\n    @JsonProperty(<span class=\"hljs-string\">\"city\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String city;\n\n    @JsonProperty(<span class=\"hljs-string\">\"residents\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">List<\/span>&lt;Person&gt; residents;\n\n    <span class=\"hljs-comment\">\/\/ Konstruktoren, Getter und Setter<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Wenn wir versuchen, eine <code>Person<\/code>-Instanz zu serialisieren, wird Jackson standardm\u00e4\u00dfig auch die zugeh\u00f6rige <code>Address<\/code>-Instanz serialisieren, und umgekehrt. Dies kann zu einem unerw\u00fcnschten Effekt f\u00fchren, da die <code>Person<\/code>-Instanz in der <code>Address<\/code>-Instanz enthalten ist, und diese wiederum auf die urspr\u00fcngliche <code>Person<\/code>-Instanz verweist, was zu einer Endlosschleife f\u00fchren kann.<\/p>\n\n\n\n<p>Um dieses Problem zu l\u00f6sen, bietet Jackson verschiedene Ans\u00e4tze und Annotationen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">@JsonManagedReference und @JsonBackReference<\/h2>\n\n\n\n<p>Eine M\u00f6glichkeit, bidirektionale Beziehungen zu handhaben, besteht darin, die Annotationen <code>@JsonManagedReference<\/code> und <code>@JsonBackReference<\/code> zu verwenden. Diese Annotationen weisen Jackson an, wie die Beziehung zwischen den Klassen verwaltet werden soll.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ Beispiel mit @JsonManagedReference und @JsonBackReference<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span> <\/span>{\n    @JsonProperty(<span class=\"hljs-string\">\"name\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String fullName;\n\n    @JsonProperty(<span class=\"hljs-string\">\"age\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> int age;\n\n    @JsonManagedReference\n    @JsonProperty(<span class=\"hljs-string\">\"address\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> Address address;\n\n    <span class=\"hljs-comment\">\/\/ Konstruktoren, Getter und Setter<\/span>\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Address<\/span> <\/span>{\n    @JsonProperty(<span class=\"hljs-string\">\"street\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String street;\n\n    @JsonProperty(<span class=\"hljs-string\">\"city\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> String city;\n\n    @JsonBackReference\n    @JsonProperty(<span class=\"hljs-string\">\"residents\"<\/span>)\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">List<\/span>&lt;Person&gt; residents;\n\n    <span class=\"hljs-comment\">\/\/ Konstruktoren, Getter und Setter<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel wird <code>@JsonManagedReference<\/code> auf das Feld in der &#8222;managenden&#8220; Klasse (<code>Person<\/code>) angewendet, und <code>@JsonBackReference<\/code> wird auf das Feld in der &#8222;r\u00fcckverweisenden&#8220; Klasse (<code>Address<\/code>) angewendet. Dies teilt Jackson mit, dass die &#8222;managende&#8220; Seite der Beziehung w\u00e4hrend der Serialisierung ber\u00fccksichtigt werden sollte, w\u00e4hrend die &#8222;r\u00fcckverweisende&#8220; Seite ignoriert wird. Dies verhindert die Endlosschleife und redundante Daten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">@JsonIdentityInfo<\/h2>\n\n\n\n<p>Eine andere M\u00f6glichkeit, bidirektionale Beziehungen zu handhaben, ist die Verwendung der <code>@JsonIdentityInfo<\/code>-Annotation. Diese Annotation erm\u00f6glicht es Jackson, Objekte mit einer eindeutigen ID zu versehen und sicherzustellen, dass dieselbe Instanz w\u00e4hrend der Serialisierung nur einmal erscheint.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ Beispiel mit @JsonIdentityInfo<\/span>\n@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = <span class=\"hljs-string\">\"id\"<\/span>)\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Person<\/span> <\/span>{\n    @JsonProperty(<span class=\"hljs-string\">\"id\"<\/span>)\n    private Long id;\n\n    @JsonProperty(<span class=\"hljs-string\">\"name\"<\/span>)\n    private <span class=\"hljs-built_in\">String<\/span> fullName;\n\n    @JsonProperty(<span class=\"hljs-string\">\"age\"<\/span>)\n    private int age;\n\n    @JsonProperty(<span class=\"hljs-string\">\"address\"<\/span>)\n    private Address address;\n\n    <span class=\"hljs-comment\">\/\/ Konstruktoren, Getter und Setter<\/span>\n}\n\n@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = <span class=\"hljs-string\">\"id\"<\/span>)\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Address<\/span> <\/span>{\n    @JsonProperty(<span class=\"hljs-string\">\"id\"<\/span>)\n    private Long id;\n\n    @JsonProperty(<span class=\"hljs-string\">\"street\"<\/span>)\n    private <span class=\"hljs-built_in\">String<\/span> street;\n\n    @JsonProperty(<span class=\"hljs-string\">\"city\"<\/span>)\n    private <span class=\"hljs-built_in\">String<\/span> city;\n\n    @JsonProperty(<span class=\"hljs-string\">\"residents\"<\/span>)\n    private List&lt;Person&gt; residents;\n\n    <span class=\"hljs-comment\">\/\/ Konstruktoren, Getter und Setter<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel wird <code>@JsonIdentityInfo<\/code> auf beide Klassen angewendet und mit einem <code>PropertyGenerator<\/code> konfiguriert. Dies stellt sicher, dass Objekte mit derselben ID w\u00e4hrend der Serialisierung nur einmal erscheinen, unabh\u00e4ngig von ihrer tats\u00e4chlichen Verwendung in der Datenstruktur.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p>Die Handhabung bidirektionaler Beziehungen in der Serialisierung und Deserialisierung von JSON mit Jackson erfordert sorgf\u00e4ltige Aufmerksamkeit, um Endlosschleifen und redundante Daten zu vermeiden. Die vorgestellten Ans\u00e4tze mit Annotationen wie <code>@JsonManagedReference<\/code>, <code>@JsonBackReference<\/code> und <code>@JsonIdentityInfo<\/code> bieten effektive L\u00f6sungen f\u00fcr dieses Problem. Entwickler sollten die geeignete Methode basierend auf den Anforderungen ihrer Anwendung ausw\u00e4hlen und sicherstellen, dass die JSON-Daten konsistent und korrekt verarbeitet werden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die Verarbeitung von JSON-Daten ist in der heutigen Softwareentwicklung von entscheidender Bedeutung, da viele Anwendungen auf den Austausch von strukturierten Daten angewiesen sind. Die Jackson-Bibliothek, eine weit verbreitete Java-Bibliothek f\u00fcr die Verarbeitung von JSON, bietet leistungsstarke Mechanismen f\u00fcr die Serialisierung und Deserialisierung von Java-Objekten. In diesem Artikel werden wir uns auf bidirektionale Beziehungen zwischen Java-Klassen [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-171","post","type-post","status-publish","format-standard","hentry","category-plain_java"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/171","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=171"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/171\/revisions"}],"predecessor-version":[{"id":172,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/171\/revisions\/172"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=171"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=171"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=171"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}