Entity Relationships Part 1: One-To-Many
Published: 2021-04-08 13:17:00

## Adding a Car Class

{% youtube FK4DHz_lrUc %}

## One-To-Many Relation

{% youtube _IpDUgAfjZA %}

#### Clarifications
At the end of the video, the `person` column in the car table (the table to the right) is called a **foreign key** column as the values in the column are ids on the person table (table to the left)

## One-To-Many Implementation

{% youtube 3gSiQCmtLHg %}

[GitHub Repo Tag](https://github.com/softwaredevacademy/spring-web-app-demo/releases/tag/car)

#### Clarification
##### Car Controller
The annotation `@Controller` was mistakenly used instead of `@RestController` in class `CarController`. `@RestController` is a newer annotation that removes the need of using a `@ResponseBody` annotation to wrap the return type in a response class. However, if you are returning the type `ResponseEntity<T>` it shouldn't make a difference.

#### CascadeType
When using a one-to-many relationship it is often relevant to set a cascade type. This decides which actions on an entity should be propagated to its collection of another entity. In our case, if we want the cars to be deleted when the person who owns them gets deleted we should set a value on the `@ManyToOne` annotation `cascade = CascadeType.ALL` for all actions (including deletion, persisting) to affect the cars. If you only want deletion specifically to be propagated then you would set the value to `cascade = CascadeType.REMOVE`. See [Overview of JPA/Hibernate Cascade Types](https://www.baeldung.com/jpa-cascade-types)

## Avoiding Recursive JSON Representation

{% youtube esvT99ST5lM %}

#### Snippets & Commands
##### JSON annotations
Ignore the property completely:
```java
@JsonIgnore
```
or make the property only be rendered as the id:
```java
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = true)
```

## Updating Car & Validation

{% youtube rTPLSALamjs %}

[GitHub Repo Tag](https://github.com/softwaredevacademy/spring-web-app-demo/releases/tag/put-validation-car)

#### Clarifications
##### Car Field Validation
At the very end of the video. The field `topSpeed` is annotated with `@NotBlank` but that annotation actually doesn't work on `int` fields because compared to a `String`, an `int` has no concept of being empty (int value 0 is not considered empty) so there you would have to use `@NotNull` instead.

##### Validation Groups
If you would like to validate an object differently depending on which method it is used (for example in one controller method you might want to enforce a non-null reference to another entity but in another you want the reference to be able to be omitted) you can use Validation Groups, see [this link](https://reflectoring.io/bean-validation-with-spring-boot/#using-validation-groups-to-validate-objects-differently-for-different-use-cases).

#### Snippets & Commands
`build.gradle`
```groovy
plugins {
    id 'org.springframework.boot' version '2.4.4'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    runtimeOnly 'org.postgresql:postgresql'
}
```

<hr>
<p style="align: center;"> <span> <a href="https://dev.to/softwaredevacademy/request-response-part-2-http-the-crud-controller-213d">Previous article</a> | </span>
<span> <a href="https://dev.to/softwaredevacademy/entity-relationships-part-2-many-to-many-4keo"> Next article </a> </span>