Spring Data JPA Relationships Tutorial - ManyToMany, ManyToOne & OneToMany

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone so today i'm going to be showing you how to create relationships between your entities using spring data jpa so first of all this is our starting application we're going to have subjects that we can create we're going to also be able to create students and we're going to be able to create teachers so with the relationships we want a subject to have many students and a subject to have one teacher and a student can have many subjects and a teacher can also have many subjects so that's where we're starting so just to show you what we have as a starting point um we basically have a student entity that has an id and a name we also have a subject entity that has an id and a name and we have a teacher entity that has an id and a name so then for each of these entities we also have a controller so we have request mapping for students that we can basically use to get the students and create students we have the same thing for subjects and we have the same thing for teachers so i didn't want to write all this code in this tutorial because this tutorial is mainly focused on using spring data jpa to create relationships between these entities so as well as the controller the controller is reaching out directly to our repository so i wouldn't normally do it like this i would usually have a service in between the controller and the repository where some business logic could go um but for the purpose of this tutorial i think it's fine um but if you're going to be using this then it might make sense to have a service in between the controller and the repository switch repository is very simple it just extends the jpi repository and we don't create any extra methods so it's the same for all three so now in our configuration in our palm we are using a h2 in memory database and we also have the spring starter web and the spring starter jpf so if you're creating this from the spring starter in the browser then you basically need to use these starters the jpa the web and a h2 so by default whenever you use h2 it has this scope of runtime i took this out because we basically want to be able to use view the database in the browser and to do that we can use this configuration uh i'll make this to the next line as you can see and this is basically allowing us to view the h2 console in the browser so my application is running here i've created my three entities so we can actually connect to this in the browser using that using this configuration and you wouldn't want this enabled in production obviously um but it's it's quite useful for debugging so here we can see we're able to get our students and as you can see we created one a minute ago and we can also view our subjects and we can view our teachers and this is just going to be useful this debugging capability because we're going to be creating relationships between these three entities so we want to be able to see how those are are mapped into actual tables so now that we have our kind of basic setup explained we're ready to get started with the relationships so first of all from the subject side we know a subject is going to have many students and a student is going to have many subjects so let's create that relationship now so first of all from the subject entity we're going to have a set a set of students and we're going to call this enrolled students and let's initialize it as a new hash set and because we want to start it off as empty so let's just import this and we want to make this private and let's just create a getter for this as well okay so now we have this private set of enrolled students and we have a getter so let's just move to getter to the bottom okay so now we have this enroll students on this side now from the student side we need to create the relationship so from this side we're going to have another set and this time it's going to be a set of subjects and let's just call it subjects and again let's create a new hash set for that and let's import that and the same thing again let's make it private and generate a getter first cool so now from the subject side we're going to start to create the many-to-many relationship so to do that first of all we're going to use this at many-to-many annotation and this is going to define a many-to-many relationship between subjects and students but in order to do this we're going to need a join table so this is going to create a new table which is going to join the subjects to the students so the name of the table is going to be student enrolled and now we need join columns this is defining what columns are going to be joined inside the table so we need to use at join column and first of all it's going to be name is subject id so this is saying we're going to create this new table called student enrolled and it's going to join using the first column which is subject id and then we need to use an inverse join column which is again at join column this time it's going to be name is equal to student id this is going to create a new join table which has one column of subject id another column of student id and this is going to create the relationship between them so now that we have the relationship from the subject side to student we need to do something on the student side to define um the same relationship so let's just move the getter down to the bottom again and this one isn't quite so complicated so we can just use that many-to-many and we're going to say it's mapped by enrolled students this is just mapping the relationship so this enrolls students it needs to correspond to this instance variable here enroll students so this is created the many-to-many relationship and where a stude where a subject has many students and a student can also enroll in many subjects so how can we use this now from our api so from the controller we're going to create a new endpoint and just to clarify that this tutorial is basically mostly around the jpl relationships and it's not so focused on the api so this this might not be the most restful way to do this or the best way to do this but it's just a way to do this so that's that's why we did it so we're going to create a new pod mapping and this pod mapping is going to have an endpoint of forward slash subjects which is defined here and then we're going to use subject id and then we're going to say students and we're going to use student id and this is going to return a subject and we just call this method enroll student to subject as we can see we've defined two path variables subject id and student id so we're going to use them here the first path variable is subject id and that is going to be a long because we've defined the id of subject as alarm and we're going to need to do the same thing for student id so now we have our two path variables cool uh so now we're going to basically need to get the subject get the student and then assign the student to the subject and then save that so that's what we're going to do here so first of all we're going to get this subject we already have the subject repository author wired here so we're able to use that so we're just going to say get one and we're going to use the subject id to get that so again if if you were actually building something with this you would need to cover the case where this subject might exist so you might need to put some extra error handling but we're not going to do that in this tutorial so now we need to do the same thing for student um but as you can see we don't have the student repository yet so this is normally why i would use a service in between the controller and the repository because it's a bit strange that the controller has access um to the student repository which is actually outside its domain so usually i would use a service class to do the connection there um but for simplicity here we're just going to do it all from the controller so we have a student repository we're going to use that student repository and again we're going to get one by the student id and i just saw up here this shouldn't be getting a subject by the student id this should be getting a subject by the subject id so now that we have that we're going to use a method called subject dot assign or dot enroll student and it's going to pass in a student so now we just need to create this method it's going to be quite simple so we already have the [Music] the enrolled students set here so we can just use that enroll students.add and we're gonna add the student that we passed in like that so going back to the controller now that has got rid of that error so now we just need to return the subject um but first of all we need to save it so we're going to return subject repository dot save and we're going to save the subject and that we just enrolled the student to so that should all work end to end there's going to be one problem here i'm just going to run it to show you the problem so because a subject has um many students and a student has many subjects whenever we use this through the api we're basically going to have this recursive problem where it's going to display all of the students enrolled to a subject but then it's going to display all of those students subjects so it's going to be kind of this recursive issue so first of all let's see if it works and then you should be able to see that problem that i'm talking about so it all runs okay which is a good sign um first of all again we're going to create a subject first of all we can see we have this enroll students which is empty which is a good thing then we're going to create a student we can see it also has subjects as an empty list but as we're going to see in a minute this is going to cause us a problem so now let's just get the subjects we can see we have we have this subject called math it has no students yet so now we're going to use our endpoint that we just created and to basically enroll a student to the subject so first of all it was a put method and it used the subject id and then it used forward slash students and then the student id to enroll that student in the subject let's just rename this to enroll student i like to keep all of my requests in postman because it just saves me a lot of time in the future i don't need to create these things again they're basically all stored in this collection which is just useful so now if we do this put to assign the subject or enroll the student to the subject we can see this recursive problem so as we can see it's it's showing the students that are not enrolled to the subject but then it's it's also shown displaying those students and their subjects and this is a recursive problem and we can see it's it's actually thrown an error here um so there is an easy way around this from the student side we basically don't want to display the subjects that a student is enrolled in we still want this relationship to be there but we just don't want to display it so we can use an annotation called json ignore to do that so if we stop this and start it again we should have everything that we need so in one second when it starts we're going to make the request post to subjects which creates this subject then we're going to create a student we can see that now if we get this subject we can see it has no enrolled students yet now if i enroll the student with id1 to the subject id1 we have an error so let's just see what's wrong there so after a little bit of debugging i found the problem so it's related to this get one method on the repository so this is um something to do with this being a lazy method so it doesn't actually receive the subject here it's getting um a reference or a lazy reference to that so instead of this get one we're going to just use find by id dot get um because find by id is returning an optional so we need to to call get on that and again this this isn't related to the relationship at all um if you were doing this properly um and you were building a production system you would need to handle here what happens if a subject this id doesn't exist or a student with this id doesn't exist you would need to handle those cases um but for this this is fine this is just an example to show the jpi relationships in action so this should be fine um that was an interesting problem that i didn't come across before so now going back to postman let's see if it works this time so we're going to create our subject then we're going to create our student and now if we get the subjects we can see that there's no student students enrolled um now if we put the student um to be enrolled to the subject we can see that the subject now includes uh john which we enrolled as a student and now we can do get subjects and to see that so one interesting part of this now is we can use this hit to console to basically connect to our database and see what's happening here so once this connects we can see that we have our tables here and we can see we have our student our subject and our teacher like before and but we now have this new table called student enrolled which was basically created as a result of this join table student enrolled and it basically creates a many-to-many relationship between subjects and students because now if we see this we can see that we have the subject and the student related here and that's what's what's doing the magic for us so if we were to create another student let's call him simon here so we've created another student and now we want to enroll simon as well so let's let's do this put two so now we can see that enroll students has john and simon if we were to go back here now um here and run this we can see that we now have both of them so they're both enrolled in the same subject and we have the two student ids here so that's cool and that's working so that's our many-to-many relationship finished so now we want to create a one um to many relationship between teachers and subjects so a teacher can teach many subjects but a subject can only have one teacher so this is a little bit different to before and it's actually easier um in my opinion so let's take a look at that first of all from the subject side we're going to have to have this field called teacher so we're going to again create a field a private field it's going to be teacher and it's going to start off just being null so that's okay um so now on this so on the teacher side we need to have subjects so we're going to have a private set of subject and again we're going to initialize this as a new hash set if i initialize that all right let's give it a name i guess subjects so let's do that cool so now we have a teacher with subjects and a subject which has one teacher so now with the relationship here on the teacher side so the teacher needs to have add one to many and we're going to map this by teacher this is defining a one-to-many relationship between teacher and subject so teacher can have many subjects again like before we would have this recursive problem so let's just assign the json ignore annotation to this as well now on the subject side we have uh let's first of all just create our getter because we're gonna need a getter for that cool and let's just move that to the bottom because we like to have all our our fields at the top and our getters and setters at the bottom cool so on the subject side we had this teacher and again let's just create a getter for that and let's put that down below cool so now let's give the annotations for this so we have a teacher this time it's many to one because i need to one because there's many subjects um and they each have one teacher um but one teacher can have many subjects this is how it differs from before so many to one here is going to be a little bit easier because we don't have a join table um first of all we're just going to pass in cascade equals just go type.all and we're going to use this join column so the name here is just going to be teacher id and the reference column name is going to be id because it's going to use the id of the teacher for that cool so again that's everything done kind of at an entity level we have this relationship defined so now on our controller we need to define a way to actually use this so let's just copy this one because it's going to be quite similar again this tutorial is not about rest this is just about the jpa relationship so there there could be a better way to do this from a controller point to make it more restful um but let's just do it like this for simplicity so we've just replaced this path variable to be called teacher id so let's rename it here as well and let's just change the name as well so let's just say assign teacher to subject so we're going to be getting the subjects like before and now we need to get the teacher like this and let's use the teacher id to get that um so now we need another method here and this is going to take the teacher as a parameter now let's just say assign teacher so now if we create that method this is just going to be basically saying this dot teacher equals teacher and again we are just going to be saving that so this isn't shouldn't be using the student repository again this would be happening normally at service level um but for now let's just do it at the controller because we don't want to create another class so let's just use the teacher repository like that because we need to use that to get the teacher so let's use the teacher repository to get that so this is everything we should be able to now assign teachers to subjects and we're going to see how this relationship is a little bit different even at the table level so i i forgot to rename this uh again it's just me going too quick uh so this pot mapping should actually have a teacher here because we basically have two endpoints serving the same thing so that was that was my mistake so now that we have these unique endpoints uh this should hopefully work so it started up we're going to do the same thing again we're going to create a subject we're going to create a second subject we're going to create a student we're going to create a teacher now if we get the subjects again we have two subjects neither of them have a teacher or enrolled students we can get the students we should have one we can get the teachers we should have one and now we're going to try to enroll the student to the subject so let's see now so now we've been able to enroll the student to the subject as we can see enroll students has one student called simon and it doesn't have a teacher yet so let's copy this and first of all rename it to assign teacher to subject and it doesn't need a payload it's a pos but it doesn't need a payload um and it's going to use the endpoint subjects the id of the subject and then teacher and the id of the teacher so if we send this now uh it should just be teacher singular so we can see now that we have this really cool relationship now where the subject has enrolled students which is a list and it has one teacher which is mr smith so we could actually do something interesting here we can create another teacher called mr pat and if we create that teacher we have this teacher called mr pat so now this teacher we can actually change the teacher here to two so now we can see we've just been able to change out that teacher and we can also assign this teacher to the second subject which we created which was math so now the second subject has the teacher but it doesn't have any students yet so this is really nice this shows that the teacher is able to be assigned to multiple subjects um and multiple subjects can have the same teacher so now just to finish out um we're going to take a quick look here and see what our tables look like so first of all we have um students let's run that we're gonna need to connect again so if we look at the students first we still have one student called simon if we look at the subjects we have two subjects um and these have a teacher id and this is because because it's one to many we didn't need this join table like we had before so we can see that the the subject table itself contains the teacher id and now if we look for teacher we should have two we can see we have mr smith and mr pat and then we have this join table which was used for the many-to-many relationship between subjects and students thanks for watching this was quite a complex tutorial on jpl relationships or building relationships using jpa thanks for watching and i hope you enjoyed
Info
Channel: Kris Foster
Views: 140,442
Rating: undefined out of 5
Keywords: spring data jpa relationships, joins in spring data jpa, spring data jpa tutorial, spring manytomany join, spring data jpa relationships tutorial, spring data manytomany, spring data manytoone, spring data onetomany, spring many to many tutorial, spring many to many relationship, spring entity relationships, spring many to many example, spring boot many to many, spring hibernate relationships, spring data join column, spring data join, spring data join multiple tables
Id: f5bdUjEIbrg
Channel Id: undefined
Length: 24min 55sec (1495 seconds)
Published: Wed Feb 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.