We would continue from Part 21. You will learn how to update a record and delete a record. You will also learn about CascadeTypes and FetchTypes in Hibernate. So let’s get stated!
- Part 1 to 7 – Setting Up
- Part 8 to 12 – Infinite Recursion, @JoinColumn, JsonManagedReference etc
- Part 13 to 16 – Retrieving Child Records
- Part 17 to 20 – Inserting New Records. Using REST Client
- Part 21 – Updating Location Details
- Part 22 – Updating User Details
- Part 23 – Updating Post Details
- Part 24 – Deleting a Post
- Part 25 – Deleting a User
- Part 26 – CascadeTypes in Hibernate
- Part 27 – Deleting a Location
- Part 28 – FetchTypes in Hibernate
Part 21 – Updating Location Details
To update Location details, follows the steps below:
Step 1: Open the LocationController file
Step 2: Copy and paste the code below
@PutMapping("/location/{id}/update") public void UpdateLocation(@RequestBody Location location) { locationService.UpdateLocation(location); }
Step 3: Open the LocationService and paste the code below:
public void UpdateLocation(Location location) { locationRepository.save(location); }
Step 4: Launch the application. Use Advanced REST Client to attempt to update a location. Set the method this time to PUT
Part 22 – Updating User Details
To update Location details, follows the steps below:
Step 1: Open the UserController file
Step 2: Copy and paste the code below
@PutMapping("/user/{id}/update") public void UpdateUsern(@RequestBody User user ) { userService.UpdateUser(user); }
Step 3: Open the UserService and paste the code below:
public void UpdateUser(User user) { userRepository.save(user); }
Step 4: Relaunch and test
Part 23 – Updating Post Details
To update Location details, follows the steps below:
Step 1: Open the PostController file
Step 2: Copy and paste the code below
@PutMapping("/post/{id}/update") public void UpdatePost(@RequestBody Post post) { postService.UpdatePost(post); }
Step 3: Open the PostService and paste the code below:
public void UpdatePost(Post post) { postRepository.save(post); }
Step 4: Relaunch and test
Part 24: Deleting a Post
Deleting a Post would be quite straightforward as the Post object does not have any child objects. So let’s get it done!
Step 1: Copy the code below and paste in the PostController
@DeleteMapping("/post/{id}/delete") public void DeletePost(@PathVariable Integer id) { postService.DeletePost(id); }
Step 2: Copy the code below and paste into the PostService
public void DeletePost(Integer id) { postRepository.deleteById(id); }
Step 3: Relaunch the application and test it using r the REST client. Either way, check that the post was deleted using H2 Console.
Part 25: Deleting a User
The question about deleting a User is this: If we delete a particular user, what will happen to all the posts belonging to this user? Well, before we answer this question, let’s try to delete a user using the method used in deleting post.
Step 1: Copy the code below and paste in the UserController
@DeleteMapping("/user/{id}/delete") public void DeleteUser(@PathVariable Integer id) { userService.DeleteUser(id); }
Step 2: Copy the code below and paste into the UserService
public void DeleteUser(Integer id) { userRepository.deleteById(id); }
Step 3: Relaunch the application and test it using REST client. Try to delete user/1. You will notice that the delete operation fails. You receive a message like:
{ "timestamp": "2019-09-02T22:23:30.879+0000", "status": 500, "error": "Internal Server Error", "message": "could not execute statement; SQL [n/a]; constraint ["FK2SF14YOUCWQSO9PDCH0UIWPEM: PUBLIC.POST FOREIGN KEY(USERID) REFERENCES PUBLIC.USER(ID) (1)"; SQL statement: delete from user where id=? [23503-199]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement", "path": "/user/1/delete" }
The reason for this error is that we try to delete a user who has posts.( an entity with child entities)
Let’s now solve this problem by talking about CascadeTypes
Part 26: CascadeType in Hibernate
The CascadeType answers the question of what will happen when you delete an object has children reference objects. Now a number of things could happen
- CascadeType.REMOVE: All the child entities are deleted (all post for the user is deleted)
- CascadeType.ALL: In this case, the operation is propagated from the parent to all the child entities
- CasCadeType.MERGE: It propagates merge operation from the parent to the child entities
- CascadeType.PERSIST: Here, the transient instance is made persistent
- CascadeType.DETACH: This cascade type removes that entity from the persistent context.
Let’s not go to far! We’ll only use the second one: CascadeType.ALL
To solve the problem simply take the step below:
Step 1: Open the User model
Step 2: Add cascade = CascadeType.ALL to the @OneToMany annotation. It would be as shown below:
@OneToMany(mappedBy="user", cascade = CascadeType.ALL) private List<Post> posts;
Step 3: Now try to repeat the delete operation and see that it works!
Exercise: As an exercise for you, try out other CascadeTypes. Let me know in the comment box below the outcome
Part 27 – Deleting a Location
This follows for the method for deleting a user.
Step 1: Copy the code below and paste in the LocationController
@DeleteMapping("/location/{id}/delete") public void DeleteLocation(@PathVariable Integer id) { locationService.DeleteLocation(id); }
Step 2: Copy the code below and paste into the LocationService
public void DeleteLocation(Integer id) { locationRepository.deleteById(id); }
Step 2: Open the User model, Add cascade = CascadeType.ALL to the @OneToMany annotation. It would be as shown below:
@OneToMany(mappedBy="location", cascade = CascadeType.ALL) private List<User> users;
Step 3: Relaunch and try deleting a location. It works too.
Part 28: FetchType in Hibernate
I would like to wrap up this course by talking about FetchTypes. This relates to how data is pulled from the repository – essentially from the database.
We would focus on two types of FetchTypes: FetchType.EAGER and FetchType.LAZY
FetchType.EAGER: This FetchType tells hibernate to retrieve the related record along with the initial query. This can be an advantage, but when the child entities to fetch is much, then it could create an overhead can jeopardize performance. For example, having to retrieve all the users in a location each time to access a Location.
FetchType.LAZY: This can be used to tell hibernate to delay the initialization of the mapping until you access it explicitly.
Do the following exercise:
- Exercise 1: Add fetchType= FetchType.EAGER to all the @ManyToOne annotation
- Exercise 2: Add fetchType=FetchType.LAZY to all the @OneToMany annotations
- Exercise 3: Test the application with the FetchTypes.
- Exercise 4: Remove all the FetchTypes and test the application again. Did you observe any change. Mention it in the comment box below.
Finally you made it to the end of this course. Thumbs up to you!
If we use
cascade = CascadeType.ALL, fetch = FetchType.LAZY
for @OneToMany relations it allows us to delete entities with child entity.
This is correct
I realized I was wrong, cascade = CascadeType.ALL will delete children entities …
If I understood correctly
LAZY and EAGER refers to loading data, I googled a bit and realized the difference, for example one user has more posts, if the fetch type is LAZY when reading from the user database, his posts will not be displayed unless we call the getPosts () method