<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Philipp</title>
    <description>The latest articles on DEV Community by Philipp (@pcabro).</description>
    <link>https://dev.to/pcabro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F801810%2F11b5686f-73a1-4de1-81e1-c4988cc11003.jpeg</url>
      <title>DEV Community: Philipp</title>
      <link>https://dev.to/pcabro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pcabro"/>
    <language>en</language>
    <item>
      <title>One-to-Many and Many-to-Many in Spring Data JPA</title>
      <dc:creator>Philipp</dc:creator>
      <pubDate>Mon, 31 Jan 2022 22:47:15 +0000</pubDate>
      <link>https://dev.to/pcabro/one-to-many-and-many-to-many-in-spring-data-jpa-5c4a</link>
      <guid>https://dev.to/pcabro/one-to-many-and-many-to-many-in-spring-data-jpa-5c4a</guid>
      <description>&lt;p&gt;&lt;em&gt;Or better: Why I struggled to build my first own REST-API&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Building a REST API is one of the basics in backend software developing, but I still hadn’t dealt with it yet. Thus, I was that guy who wasn’t on that party everyone talks about - I needed to change this.&lt;br&gt;
Luckily, there are tons of opportunities to include a REST API in a project. My project is a portfolio website – also a thing fancy developers should have. Therefore, I started to read into that topic and structure my tech stack (Angular, Spring, Azure SQL Server).&lt;br&gt;
For my backend I’ve chosen Spring, if you are familiar with it then you are probably already a fan of Baeldung – a perfect website to learn about the Spring Framework. They helped me a lot and without their guides and tutorials I wouldn’t be where I am now (my thesis was written in Spring Boot). So, Kudos to you guys!&lt;/p&gt;

&lt;p&gt;But now to my REST API...&lt;/p&gt;

&lt;p&gt;The data model is quite simple: a &lt;em&gt;Project&lt;/em&gt; entity which can have several &lt;em&gt;Skills&lt;/em&gt; that are used in it. Additionally, there is an &lt;em&gt;Employment&lt;/em&gt; entity with details about the company and role. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V3m77VxS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/class%2520diagram.drawio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V3m77VxS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/class%2520diagram.drawio.png" alt="Simplified Class Diagram" width="700" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  ☝ --&amp;gt; 🖐
&lt;/h1&gt;

&lt;p&gt;Between &lt;em&gt;Employment&lt;/em&gt; and &lt;em&gt;Project&lt;/em&gt; is a &lt;strong&gt;One-to-Many&lt;/strong&gt; relationship. Nothing special – I just followed the tutorial on &lt;a href="https://www.baeldung.com/hibernate-one-to-many"&gt;Baeldung&lt;/a&gt;. For these two entities I went with a bidirectional relationship, means that I am able to access &lt;em&gt;Projects&lt;/em&gt; from &lt;em&gt;Employments&lt;/em&gt; and &lt;em&gt;Employments&lt;/em&gt; from &lt;em&gt;Projects&lt;/em&gt;. For better understanding, I added my model classes in a shortened version below. Annotations like @Getter, @Setter and @Data are from Lombok - a nice little library to reduce boilerplate code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GdDD3doI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/Employment.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GdDD3doI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/Employment.png" alt="Employment Class" width="880" height="665"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In line 17 of &lt;em&gt;Employment Class&lt;/em&gt;, you can see the &lt;em&gt;@OneToMany&lt;/em&gt; annotation for field &lt;em&gt;projects&lt;/em&gt;. The attribute &lt;em&gt;mappedBy&lt;/em&gt; aims on field &lt;em&gt;employment&lt;/em&gt; of my &lt;em&gt;Project&lt;/em&gt; class. I could leave it like that, and it would work, but I want a bidirectional relationship. Therefore, the field &lt;em&gt;employment&lt;/em&gt; of my &lt;em&gt;Project&lt;/em&gt; class needs a &lt;em&gt;@ManyToOne&lt;/em&gt; annotation as you can see below (&lt;em&gt;Project Class&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WHjVWqSc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/Project.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WHjVWqSc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/Project.png" alt="Project Class" width="880" height="733"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Until now it wasn’t a big deal except for one little recursion issue on my &lt;em&gt;Employment&lt;/em&gt; entity, because of the fact, that my Json response of an &lt;em&gt;Employment&lt;/em&gt; object includes the related &lt;em&gt;Projects&lt;/em&gt; and these having an &lt;em&gt;Employment&lt;/em&gt; object each with their &lt;em&gt;Projects&lt;/em&gt; and so on. I tried to fix that issue by adding &lt;em&gt;@JsonIgnore&lt;/em&gt; to field &lt;em&gt;projects&lt;/em&gt;. However, by adding this annotation, a field or method is being “ignored by introspection-based serialization and deserialization functionality. That is, it should not be consider a ‘getter’, ‘setter’ or ‘creator’.” – according to the &lt;a href="https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonIgnore.html"&gt;fasterxml documentation&lt;/a&gt;. Important to notice, that the whole &lt;em&gt;projects&lt;/em&gt; field is ignored, so that we’re getting an &lt;em&gt;Employment&lt;/em&gt; object in our response without any sign of the related &lt;em&gt;projects&lt;/em&gt;. Oh dear, did I struggle with this annotation. At this point I was going in circles, cause my assumption was that I found the right annotation and was missing something else. After what felt like an eternity, I finally read about &lt;em&gt;@JsonIgnoreProperties&lt;/em&gt;. Essentially the same but instead of ignoring the whole object, it is ignoring just individual fields/properties. In my case, it is ignoring the &lt;em&gt;Employment&lt;/em&gt; field in my &lt;em&gt;Project&lt;/em&gt; objects.&lt;br&gt;
The recursion is gone and the One-to-Many relationship works fine. My next step was to implement a Many-to-Many relationship. So, I used my advanced Google techniques to find a good way to do it. 😎&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xJRAs5Bj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xJRAs5Bj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/giphy.gif" alt="Google Search" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🖐 --&amp;gt; 🖐
&lt;/h1&gt;

&lt;p&gt;There are several different approaches to handle the &lt;strong&gt;Many-to-Many&lt;/strong&gt; relationship between &lt;em&gt;Project&lt;/em&gt; and &lt;em&gt;Skill&lt;/em&gt;. According to the &lt;a href="https://www.baeldung.com/jpa-many-to-many"&gt;tutorial on Baeldung&lt;/a&gt; you need to create a join entity class, if you want to add attributes to your relationship. Therefore, I added one for my join table &lt;em&gt;ProjectSkills&lt;/em&gt; (see “&lt;em&gt;Simplified Class Diagram&lt;/em&gt;”), because of the &lt;em&gt;usageInPercentage&lt;/em&gt; attribute. &lt;br&gt;
A join table primary key consists of foreign keys, a so-called composite key. In Spring you need to consider this for your join entity class. In figure &lt;em&gt;ProjectSkills Class&lt;/em&gt; you might notice &lt;em&gt;ProjectSkillsKey&lt;/em&gt; field with the &lt;em&gt;@EmbeddedId&lt;/em&gt; annotation - that is our composite key. For the sake of completeness, I also attached the &lt;em&gt;ProjectSkillsKey Class&lt;/em&gt; below. It simply combines our both foreign keys.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oztftyJb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/ProjectSkills.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oztftyJb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/ProjectSkills.png" alt="ProjectSkills Class" width="880" height="887"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1wmsBkrA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/ProjectSkillsKey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1wmsBkrA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/philippcabron/images/master/ProjectSkillsKey.png" alt="ProjectSkillsKey Class" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having a join entity class dissolves the Many-to-Many relationship and converts it into two separate One-to-Many relationships. Except for one small difference, this structure is identical to the relationship between &lt;em&gt;Employment&lt;/em&gt; and &lt;em&gt;Project&lt;/em&gt;. The difference: Another annotation is needed - &lt;em&gt;@MapsId&lt;/em&gt;. It is used to indicate which the primary key of the annotated attribute is.&lt;br&gt;
After implementing the &lt;em&gt;ProjectSkills&lt;/em&gt; class, all needed relationships were portrayed. Thus, I was done with my entities. After all, I know, this is neither new nor exciting stuff, but it still gave me a good feeling to do it and write about it. &lt;/p&gt;

&lt;p&gt;Thank you for your attention! Additionally, I am new to writing blogs, especially in English. Tips, tricks or language corrections are welcome! Many thanks in advance! ❤️&lt;/p&gt;

&lt;p&gt;And don’t forget to add &lt;em&gt;@JsonIgnoreProperties&lt;/em&gt; to avoid recursions! &lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
