Java Spring Boot - JPA - Hibernate - H2 - One To Many - REST Web Service - RESTful API

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys codeforge here welcome to the next video today we'll build a when to money relationship for our web service we'll start with creating two entities one of them will be the cart entity and the second one will be the item entity the cart entity will be the owning site and we'll be able to add different items to our cards after creating one-to-many relationship we will move forward and we'll build the service layer where our logic will live and after that we'll build the rest part so at the end we'll be able to call different endpoints to perform operations on our entities okay so this is our project setup of course we will use java springboot and the most important part over here is the right side which are the dependencies we'll use the spring web so we'll be able to create rest endpoints we'll also use spring data jpa so we'll be able to create entities and create a relationship between them for testing our database layer we will use the h2 in memory database and at the end we have the lombok dependency which is a java annotation library and basically it will speed up our development process and if you don't know what the loan block is i have a separated video on my channel so you can learn there how to install it in your springwood project and how to use it and what are the most important or useful annotations and also regarding the one-to-many relation there is also a video where i'm explaining step by step how to build such a relationship okay so i think we are ready everything is covered so we can generate the project and import it in the intellij let's go okay project is imported so in the first place we would like to navigate to the source main resources and over here would like to open application properties file over here i will paste some properties which we are using in almost every video related to the jpa and if you don't know what's going on over here i encourage you to check out the video with the edge to set up where i'm explaining those properties and now to build our relationship we will need entities so let's create them we will go to the java and we'll open our main package and over here we'll click create a new package which we'll call model and inside we'll create two classes one for each entity so we want to right click it select new java class and the first one will be called cart and the second one will be called item let's start with the card class and first thing we have to do is to mark it as the entity and to do it we have to use the entity annotation we'll also use the table annotation to specify the name of the table which will be created for this entity we have to import it and we'll give it a name of card our cart entity will need the primary key and to create one we have to use the id annotation and we'll also use the generated value annotation and we'll set the strategy to the generation type auto and of course we want to put it on the field so we'll create a private long field with the name id our card will have also name so we'll go and create another property so it will be private string and we'll call it name now we would like to store items in our cards and to do it we'll create a private property which will be the type of list and this list will store objects of type items so we have to provide item over here and import list we'll call this property items and we'll also assign memory to it so it will be new arraylist but it's not everything we also have to mark our items collection with the one-to-many annotation and also we'll specify the cascade type and we'll set it to the cascade type all so each operation performed on the card will be cascaded to the items so if we will delete the card which stores let's say two items the card will be deleted together with those two items we'll also specify the join column name by using join column annotation and we'll set the name of it to cart underscore id so thanks to that in the item table we'll have the cart id column and this card id column will tell us to which card the specific item is assigned our entity is not ready yet because we will also need the default constructor and to create one we'll hit alt insert we'll select constructor and from here we'll select non we also need two methods one for adding items to the items collection and one for removing them so let's create them we'll go to the bottom and over here we say public void and the first one will be called art item and it will accept the item object as the argument and all we have to do inside is to use our items collection and call add and here we'll pass the item object which will receive now we want to remove the items so let's go to the bottom and we'll say public void this time it will be remove item and again we will get the argument that is the type of item and we want to access our items collection which stores the items and you want to call the remove method and we want to pass the item object as the argument before we will move to the item entity we will also mark the card with the data so the getters and setters and also constructors will be generated for this entity and by the way it's the lombok annotation okay so let's move to the item entity in the first place we will mark it with the data annotation it would be useful or later and now we'll mark it with the entity also and we'll specify the table name and we'll set the name to the item we'll also need the primary key so we'll use the id together with the generated value and we'll set the strategy to auto we want to put it on the private long id field each item will also have the serial number so we'll say private string and we'll call this field serial number and this is pretty much everything regarding the properties we'll also generate the default constructor for the hibernate for now it's good so we can move on and create our new package in our main package and it will be repository repositories allow us to perform the operations on our entities like retrieving them from the database saving them to the database or deleting them so we'll need one repository for each entity so we want to right click the packet select new java class this time it will be interface and the first one will be cart repository let's also create the second one for the item so again we select interface and it will be item repository all we have to do over here is to mark our interface with the repository annotation and also we have to say that our item repository extends crude repository which is the generic type and we have to specify for which entity we are creating this repository so in this case it will be the item and we have to import it and as the second part we have to specify the type of the primary key and this is it we have to do the same for the card repository so again we will mark it with the repository annotation we want to say extend screwed repository but this time we want to create it for the card and the type of the primary key is also long now we will create the service layer so we want to right click on our main packet select new package and we'll call it service inside we would like to create two classes one for each entity so we select java class and first one will be cart service and the second one will be item service let's start with the item service in the first place we'll mark it with the service annotation so spring will create a bin for this class our item service will have one field and it will be private final it will be the type of item repository with the same name and now we would like to inject this field to our item service so to do it we'll generate a constructor with this specific field and also let's mark it as the out wired over here we are using something that is called dependency injection in the spring so spring will inject the item repository bin to our item service thanks to that we'll be able to use item repository methods in our item service class now we have to create several methods so we will be able to perform crude operations on our item entity and the crude stands for create read update delete and in the first place we'll take care of creating the items to do it we'll create a public method which will return the item because it is nice to return the object after creating it and the method name will be add item and it will accept item object as the argument and all we have to do to persist our item object into the database is to say return and you want to call item repository dot save item and as you can see over here we are using the item repository which is injected by the spring and thanks to that you can call the save method to save our item entity and after that we are returning the persisted object and now we would like to take care of r which is read so we'll create the method that will return all of the items from the database so we'll say public and since we will be returning all items will return the list of them so we want to say list item and we probably have to import it and we'll call this method get items and let's scroll it down now to get all of the items we have to say return and again we will use item repository which is our layer that communicates with the database and we'll call find all methods and it should return all of the items from the database but as you can see we are getting an error here because the required type is list item which is specified over here and the find all method will return the iterable so now we have to convert the iterable into the list to do it we'll use the stream support so we say stream support over here and we call the stream method to create a stream out of our item repository find all the result but this stream works on the splitterators so we have to call this iterator method on our find all result as the second argument of the stream method we can specify if the return stream will be sequential or parallel and we want to make it sequential so we have to pass false and the last thing we have to do over here is to collect the result of the stream so we have to say dot collect and we can see that we are passing collectors to list because we want to convert the stream to list okay so we can retrieve the list of the items it would be also nice to retrieve one specific item in the case when the user would like to check the details of this one specific item so we will go over here and we'll say public and we'll return the item of course and our method will be called get item this time and you can get item by id so our method will accept argument that is the type of long and the name will be id hiding an item is really easy in the first place we'll say return and again we will use our database access layer which is item repository for this specific entity and we call the find by id method and over here we'll simply pass id but as you can see we are getting an error and this is because the find by id method is not returning the item but the optional item so item with this id may not exist on our database when the find my id method will not find the specific item we can throw an error so we can call oralstro method and we can pass the lambda expression and this lambda expression will create a new runtime exception but this runtime exception is not a really meaningful one so we'll create our own exception we will go to the model package we will right click it select new package and we'll say exception over here we'll call our new exception card not found exception so the first thing our exception has to do is to say extends runtime exception and now we'll create a constructor so it will be public card not found exception and it will accept id and inside our card not found exception constructor will call the super constructor from the runtime exception and we'll pass the message there so we will use the message format to format the message and we call the format method and now we'll provide the pattern so it will be could not find card with id and we'll use the placeholder here and as the second argument of the format method will pass the id and this is our exception so now we can go back to our item service and instead of throwing runtime exception we can throw our cart not found exception and we can pass the id so we will have a meaningful error now we would like to take care of the delete method so again it will be public will return item because it's also a nice practice to return the deleted item so it will be the delete item and of course we can delete it using id so in the first place we have to check if this specific item exists on the database because we cannot delete something that does not exist i will say item item to create a object and we'll call our existing method from the service which is get item and we'll pass id and our getitem method which we have created second ago will make a validation because if it will not find the item itself and the error will be thrown so it is good to go and now if the item will be found we want to simply delete it so we want to call item repository dot delete and we want to pass the item and now we can simply return the item and last thing we want to do is to edit the item and it will be easy because our item entity has only one field which is the serial number so now again we want to say public item and it will be called edit item and will accept id and the item item so the first parameter of this method long id will be used to retrieve existing item from the database and the second parameter which is the item will be used to update the existing item so in the first place we have to check if the item exists on the database and if it's there we have to retrieve it so we'll create an item type variable with the name item to edit which will store the reference to the object and we want to do the same what we have did in the delete item method so we'll call the getitem method so we'll pass id and thanks to that we will have again a validation because if the item with the specific id will not be found the getitem method will throw an error and now we would like to update our item it will be pretty easy because we have only one field so in the first place we want to use the item to edit object retrieved from the database and we want to call the set serial number method and by the way this set serial number method comes from the lombok it's generated by the lombok and as we can see over here in the item we don't have any setter this is because this annotation generates it okay so let's go back over here and all we have to do is to call the item and the same goes for the get serial number it's also generated by the lombok so basically we are retrieving the serial number from the incoming item object which is the new object and then we are setting it on our existing object to update the serial number and thanks to that item to edit is attached or also called managed entity we don't have to explicitly save it so all we have to do over here is to say return item to edit and our changes will be persisted okay so this is all regarding this item service i have to fix one more thing over here you probably already seen this i have created card not found exception which definitely makes no sense over here so of course it should be item not found exception so let's quickly refactor it we can right click on our exception select refactor rename and we'll change the cards to the item we'll hit enter we can see that the name over here has been changed also over here and let's also navigate over here and we'll change the message so it will be could not find item instead of cart and now we can go back to item service and now it's good we can move on to the card service and take care of this one so in the first place we'll mark it with the service annotation this class will have two dependencies first one will be for the card repository because we will be working a lot with the card entities and also we'll need dependency to the item service because we will have to take care of adding items to the cart and removing them let's generate the constructor for it we want to hit alt insert constructor we want to select both of them and we want to hit enter we also add the outwired annotation like in the case of items we will need the method to add new cards so we'll say public it will return the card and the name of the method will be add card we have to import the card type and will accept a card object as the argument and we can simply say return card repository dot save and we can pass the card as the argument so it is almost the same like in the case of items same goes for retrieving all cards from the database so let's maybe copy this method from here so we'll copy this we'll paste it in the cart and of course we'll change the type from the list item to the list card we change the name of the method to the get card and we of course want to use the card repository instead of item repository and the rest stays the same oh we'll add the s at the end over here next method will be related to retrieving the specific card so we will say public card because we will be returning the card object get card and of course we want to retrieve the card by id so we'll have the argument type of long with the name id and to find it we'll say return card repository find by id and we'll pass the id as the argument and of course like in the case of the items we'll throw an error if the specific card will not be found so we'll use the lambda expression over here and we'll throw new runtime exception but like in the case of items it's better to create a specific exception so we will go over here right click on the exception package and create new class and this time it will be cart not found exception so in the first place we will extend runtime exception and the constructor part will copy from the item not found exception so i'll grab this and we'll paste it over here we have to change the name of the constructor of course and the message so it will be not item but cart and we can go back to our card service and instead of drawing runtime exception we want to troll cart not found exception and pass the id now we would like to delete cards so it will be public card delete card method and we'll accept id and in the first place you would like to check if the card exists and if it does we would like to retrieve it so we'll create a variable with the type card which will store the reference so it will be card card and we want to call the credit card method and pass the id and just like before the get card method will take care of finding the specific card and if it does not exist the cards not found exception will be thrown and if the card exists we want to say card repository dot delete and we want to pass the card object at the end we can simply return it by saying return card and the last method which we will use for editing the card so we'll start with the public and we will return the card and the name of the method will be edit card and we'll have two arguments first one to find the specific card and the object card with the new values so in the first place we would like to find the specific card so again we'll create a variable that will store the reference and we'll call it card to edit and we'll call the getcard method and we'll pass the id and now we would like to update the name of the card so we want to say cars to edit and now to set a new name we want to say set name and you want to update it with the value that comes from the card get name and the last thing we want to do is to return updated object so we want to say return card to edit and we don't have to explicitly save card to edit because it's managed entity or also called attached entity okay so we have the crude functionality for our cart entity and now we would like to take care of adding items to the cart and removing them so we'll go over here and we'll say public card because we want to return the card after adding the item to it and we'll call the method add item to cart and we'll have two ids over here so we'll say long card id and also we'll have long item id so to add item to the card first we have to retrieve the card itself and we'll do it the way like we did it in the case of deleting the cart and editing so we are creating the type of cart variable with the name card which will store the reference and we will retrieve the card using get card method and we'll pass the card id okay so we have the card now we will also need the item which we want to add and to do it will create item type variable with the name item and this time we'll call the item service to access the get item method and thanks to that we can pass the item id and we can retrieve the item from the database so we have both sides of the relationship and now adding item to the card is pretty straightforward so we are using the card object and we want to add new item to the collection of items and we can simply pass the item which we also have retrieved from the database since the cart entity is managed in this case we can simply say return card the last method that we want to implement is for removing the items from the card so we want to say public cart and this time it will be remove item from cart and again we'll have two parameters first one type of long card id because we have to know from which card we want to delete the item and the second parameter which is the item id again we have to retrieve the item and the card so we will copy those part and paste it and now we can remove the item from the card by using the card object and calling the remove item method which we have implemented and now we can pass the item object at the end we would like to return the cart object so this is all regarding the service layer now we can move forward and implement the rest controllers let's clear it a little bit and now we'll create a new package so we right click select package and it will be called controller we'll have two controllers first one will be called cart controller and the second one will be called item controller let's start with the item controller so in the first place we'll mark it with the rest controller annotation and also we specify the request mapping so this will be the common part for each of the endpoints and it will be slash items our item controller will require one dependency and it will be the item service so we want to say private final item service and this field will have the same name as the type and now we'll generate the constructor and we'll mark this constructor with the height wired annotation let's start with creating an endpoint for adding new item so we'll use for it a post mapping annotation because we want to use the post request for creating new items and of course we want to put this annotation on our method so it will be public and we will be returning response entity which is the generic type and it will be the wrapper for the item dto object which will create in a while and the name of the method will be add item and as the argument it will accept the request body so we'll use the request body annotation over here and the request body will be final item dto item dto so we'll receive item dto object in the request body and later on we'll do some action on it and after it we will return the response entity together with our created item and by the way dto stands for the data transfer object so now let's create the dto object and we will create it in the model package and we'll create a new package inside that will be called dto so we'll have a new class that will be called item dto and we'll also need dto for the card so we'll create a second one and it will be called card dto we will start with the item dto because this is the one we need right now in the first place we will mark it with the data notation from the lombok and our dto will have two fields first one will be private long id and the second one will be private string serial number it is the same like in our item entity and our item dto will have one special method which will allow us to transform item object into the item dto object so it will be public static and we will be returning item dto the name of the method will be from and it will accept item object as the argument it is a static method because we don't want to create an object to use it and in the first place this method will create a new item dto object so we'll say item dto with the same name so this is the variable that will store the reference and now we'll use the default constructor to create an empty object and this default constructor comes from the data annotation from the lombok so we have empty item dto object and now we want to set its fields so in the first place we want to say item dto and we want to set id and this id comes from the item get id and the same goes for the serial numbers so we want to set the serial number for the item dto and we can retrieve this serial number from the incoming item object by saying item get serial number at the end we can simply return our new item dto object so this is the gto for our item entity and now we can go back to the item controller and we can import the item dto okay so we can transform item into the item dto but we will also need to transform item dto into the item so now we will navigate to the item entity and over here we will create very similar method it will be also public static but this time you want to return item the name will be also from but this time this method will accept item dto instead of the item and now we can simply create a new empty item object by saying item item and using the default constructor and now we can say item set serial number and this serial number will come from the item dto so we'll say item dto get serial number at the end we can simply return our new item object by saying return item we need to set up only the serial number because we'll be using this item dto to item transformation method only in the case when we will be creating or editing a new item and when we are creating or editing new item we can change only the serial number by the way we don't need this default constructor over here so we can get rid of it and this is because it will be auto generated thanks to that data annotation that comes from the lombok and the same goes for the cart so we can also remove this constructor from here because we also have this data annotation let's go back to the item controller and we'll finish the implementation of the add item method so in the first place we would like to create a variable that will be the type of item and the name will be the same and we will store over here the reference to the item object that will be created by the item service so we want to say item service because we want to create a new item and we'll call the method from the item service that we have created and it is add item and we can see that it accepts item object so to actually call this method with the item object we have to use the static method from the item class which we have implemented and now we can pass the item dto so the incoming item dto will be converted into the item and the add item method will be called so our item object will be created and persisted after that we want to say return new response entity and we will convert the bug item into item dto by saying item dto from item and as the second argument will pass the http status okay so this is our endpoint for adding items and now let's take care of retrieving them so for retrieving we would like to use get mapping annotation so it will be http get method used under hood and we will create a public method and we will return response entity and this time it will be the list of item dtos so we want to say list item dto we have to import the list and we'll give it a name and it will be cat items now let's retrieve the items and to do it we'll use the item service dependency and we'll simply call the get items method and we know that this get items method will return the list of the items we can see it over here so we have to store this item somewhere so let's create a list that is the generic type so we have to say that will be the list of the items and we will say that this list will be called items so now we have to convert each item in the list into the item dto in the first place we'll create a list that will store the collection of the item dtos so we want to say list item dto and the list will be called items dto now we would like to iterate over the items collection and for each element in this collection we would like to call from method from the item dto class and to do it we want to say items we want to use the stream and now we can all the method for each element using the map method inside the map method we can specify which function should be called for each element and over here we can use the lambda expression but in this case we'll use the method reference and we want to reference the method from the item dto class and now we'll use the double colon and we'll give the name of the method which we want to call so we want to call the from method from the item dto class by the way this double column syntax is called range operator and now the final step is to convert the stream into the list so we can simply say collect collectors to list at the end we can simply say return new response entity and we want to pass the items dto collection with the http status okay next endpoint on our list is related to getting the specific item and to do it again we'll use the get mapping annotation but this time we'll specify the value for this get mapping annotation and it will be set to the id like this of course we want to attach this annotation to our method so it will be public and we want to return response entity and we will be returning item dto and now the name of the method will be get item and now it will accept a path variable i want to say path variable and it will be final long id so if you want to accept something as the path variable like we did it over here you have to specify the name of this path variable in the get mapping like we did it over here or on the controller level over here in the request mapping and now we will retrieve the item so first we need the variable which will store the reference to this object and it will be the type of item with the same name and now to actually get the specific item we'll use our item service and we'll call the get item method and now we can simply pass the id that comes from the path we have the object so we can simply return it we want to say return new response entity and over here before returning it we have to convert it into the item dto so we want to use the item dtl static method called from and we want to pass here our item object and as the http status will send ok next on our list is delete endpoint and we'll use delete mapping annotation to do it and now we'll create a method which will be public and we'll be returning response entity and it will be the item dto method itself will be called delete item and it will accept path variable like in the case of get item so we'll copy it and paste it over here and of course we have to specify the value so again we'll set it to id the body of this method will be almost the same so we'll simply copy it from the get item method and we'll paste it in the body of delete item method the one thing we want to change is to change the method that is called in the item service so instead of the get item we want to call delete item the last endpoint is the endpoint for editing the item so we'll use for it the put mapping annotation and again we'll specify the value and we'll set it to id and we'll of course attach it to our method which will return the response entity and it will be a item dto and the method will be called edit item this method will need two things the first one is the id which will be passed as the path variable and the second one is the request body in the case of the path variable we can copy this part of code and for the request body we say request body and we want to accept item dto type with the same name and let's move it and now the body of our method it will be quite simple first of all we want to create a variable that will store the reference to the item object and let's call it this time edited item and we want to assign to it the result of the item service edit item method and this edit item method requires id which will have from the path and also it requires the item object and to get item object we have to use the static method from the item object so we want to say item from item dto and this item dto will of course come from the request body and after editing it we can simply return it so let's copy the line from delete method and we'll paste it and we only have to change the item to edited item and it is good to go so the next step is to implement the card controller so let's move there in the first place of course we'll mark it with the rest controller annotation and also we'll use the request mapping annotation to specify the common path for each endpoint and it will be slash cards our controller will need only one dependency and it will be private final card service with the same name and we'll also generate a constructor for it and we'll mark it with the autowired annotation so the first endpoint will be responsible for adding new cards like in the case of item controller we'll use the post mapping annotation and we'll put it on the method which would be public and will be returning response entity but this time we'll be returning a card dto as the object and the name of the method will be add card and our endpoint will also accept a request body so we will specify it as the parameter so we want to say request body and it will accept final cut dto with the same name and of course we have to import this class because we have created it earlier but now we'll also implement it in the first place we'll mark it with the data annotation from lombok and our card dto will have the same fields as our card entity so we'll have private long id also we'll have private string name and the last one is private list with the items so it will be the item type over here which we have to import and the same goes for the list and we'll give it a name items and we'll assign memory so it will be new arraylist we'll also need the public static method that will allow us to convert a card object into the card dto object so it will be public static rtdto this is the return type and the name of the method will be from and we want to accept the card object as the argument so the parameter will be cart inside our method in the first place you want to create a new card dto object so we'll use the default constructor generated by the lombok and now we can set specific fields so in the first place we want to set the id and we can get this id from the cart object so we want to say get id and the same goes for the rest of the fields so we want to say card dto set name and we want to retrieve the name from the card object and the last one which is the list of items so we want to say set items and from the card object we can get the list of the items at the end we want to return our new object so we want to say return card dto so we can convert the card object into the card dto but we also need to do it from the other way so we have to uh create a method that will convert card detail into the cart let's move to the card class let's zoom it a little bit and over here at the bottom we want to create a new method so we want to say public static and we want to return the cart object this time the name will be from and will accept the card gto as the argument like this so in the first place we want to create a new card object and this time we'll also use the default constructor and now we can set a specific field and in this case we want to set only the name because when we will create the card we'll be setting only the name of the card because it will be empty card and also id will be auto generated and the value for the name we can get from the card dto get name at the end we can simply return our new object by saying return card we can go back to the card controller and continue the implementation of the post endpoint in the first place we would like to create a variable which would be the type of card with the same name which will store the reference to the object that will be returned from the card service add card method and over here we can use our new method from the card class so we want to say card from and we want to pass the card to dto after creating a new card we want to return it so you want to say return new response entity and we want to convert it back to the cards dtos so we want to say car to dto dot from cart and http status will be okay now let's create an endpoint for retrieving collection of the cards and for that we will use the get mapping annotation and we'll say public response entity means we'll be returning the collection you want to say a list of the card details and we have to import the list of course and the name of the method will be get cards and also let's go down and now in the first place we have to retrieve the cards from the database and we can do it using our service layer so in the first place we will create a collection that will store the list of cards and the name will be cards and now we can use our card service and call get cards method like in the case of items now we have to map each card into the card dto so let's go to the item controller and we'll copy this line and we'll paste it over here we have to do a few adjustments so in the first place we'll change the type of our list into the cart dto and we'll change the name of our list so it will be cards dto also we want to use parts collection instead of the items collection and we want to use the from method but we want to use it from the card dto class not from the item detail and now we can simply return it so we want to say return new response entity and it will be cards dto and ok status now let's take care of getting a specific card and again we'll use the get mapping annotation but this time we'll use the value to specify the path parameter and we want to get the id in the path and of course you want to say public response entity will be returning the card dto object and the name of the method will be get card and let's go down our get card method has to accept one path variable so we have to say path variable final long id and now we can take care of the body of our methods so in the first place we'll store our object in the variable and we want to get it from the card service and you want to call the get card method and pass the id after this we can return our object by saying return new response entity and we have to convert it to the card dto using from method and we have to pass the card object and set the status to okay deleting the card will be very similar so let's copy this get method and we'll paste it over here and all we have to do is to change the mapping to delete mapping we'll change the name of the method to delete cart and also we'll change the method which will be called on the card service object and it will be delete card rest stays the same and now we can take care of editing endpoint so let's again copy this with paste it over here and we'll change delete mapping into the boot mapping we'll also change the name of the method to the edit card and will extend the parameter list so we have to add the request poly over here that will be final and it will be the card dto object and of course we have to change the methods that is called on the card service object so we want to say edit cart and we have to pass also the order parameter that has to be converted into the cart object so you have to say card from card gto so the crude functionality for our card entity is here but we'll also need two extra end points one for adding items to the card and one for removing items from the card let's start with adding and for this one we'll use the post mapping annotation and we'll specify the path so we want to say value and this time we will need two path variables the first one will be the card id because we have to know to which card we want to add the item and now we'll give it a slash items and we will also pass the item id because we have to know which item we want to add and at the end we'll give the name of the operation so it will be for the adding the items and now we want to create a method so we'll say public response entity and will be returning the card dto object and the name of the method will be add item to cart and it will have two parameters the first one will be the path variable which will be final long and the name will be the card id and the second one will be also the path variable which will be final long but this time it will be the item id now to add item to the card we have to call our card service method but we of course want to return our card object so first let's create a variable with a type of card and now we want to use our card service and it has the add item to cart method and we will pass our two path parameters so in the first place we will pass card id and as the second parameter will pass item id after adding item to the card we want to return the card with all of the items so we want to say return new response entity and inside we have to convert the card into the card dto so you want to say card dto from art and the status will be okay and the last endpoint that we have to implement will be for removing the items from the cart so we'll copy our adding item logic and we'll paste it over here and we'll need to change the post mapping into the delete mapping and we'll also change the name of the operation and it will be removed we also need to change the name of the method so it will be remove item from cart and of course we have to change the method that is called in our card service so it will be remove item from card and the rest stays the same okay so we have created all of the end points that our application requires to work we need to do one more adjustment in the services layer so let's go to the item service in the first place and over here we want to take care of the edit item method when we were implementing this method i have said that we don't have to explicitly save the item to edit using the item repository and it is true but the class or the method itself must be annotated with the transactional annotation and if we scroll up we can see that our item service is not annotated with the transactional so we'll annotate our method we want to add the transactional at the top and now our edit item will be edited and persisted into the database with the updated url number and the same rule applies to the card service so if we open it up we can see that our edit card has no transactional annotation and same applies to the class so we will go and add the transaction over here we should also put transactional on our add item to cart method and remove item from cart method because also here we are not using the save method from the card repository so we'll add transactional over here and also over here and i don't like one thing about the add item to card method because right now if we will add item to the and then we'll try to add same item to different card it will be moved from one card to another and we don't like it so before adding item to the card first we want to check if this item is already assigned to some card to do it we'll need the bidirectional relationship between our entities right now it is a unidirectional because we have the information about the mapping only in the cart entity so let's add it also in the item so over here right under their serial number we want to add a many to one annotation and we want to put it on the private cart type field okay so right now our relationship is bidirectional and before we will implement our logic let's first create a proper exception that will be thrown when the item is already assigned to the card so we want to go to the exception we want to right click select new java class and our exception will be item is already assigned caption so over here we need to extend the runtime exception and we'll create a constructor for our exception so it will be public we'll copy the name and it will accept two different arguments so the first one will be the type of long and it will be item id and the second one will be the type of long but it will be the card id and our arguments should be also final so let's modify it and the same should apply here in the cards not found exception this id here should be final and in the item not found exception this id can also be final so let's go back to the new exception inside our new constructor we would like to call our parent constructor to do it you want to use super and inside we would like to pass a message which we want to format and the message will be following it will be item and over here we'll put placeholder for the item id and we'll say is already assigned to cart and over here we will put placeholder for the card id as the second argument we will pass item id and as the third argument it will be cart id and of course we need a semicolon at the end okay i think we have everything we need so we can go back to the card service and over here in the add item to cart method right before the add item operation we want to put if statement in the condition we would like to check if the item is assigned to the card and we can do it in the following way we will use the objects class and we'll call a static method non-null and we want to check if the card from the item object is not null so we can do it by saying item get card if that condition is true that means the item is already assigned to some card and in this case we would like to throw a new error so we want to say throw new and it will be item is already assigned exception and as the argument we have to pass item id and the second one is the card id and we can get it from the item get card get id let's move it to another line and the semicolon at the end okay so now we are safe and it is not longer possible to steal an item and put it in the another cart there is one more thing i want to change before we'll test it so let's go to the dto and over here let's navigate to the card gto and over here we can see that our card dto has a field which is the type of the list item and it is not really okay if the dto object is using the entity as the field so we'll change the item into the item dto to do it we will change the type in the list so it will be item dto and we will also change the name of the field so it will be items dto and now we have to iterate over the list of the items from the cart object and we have to transform each of them into the item dto and this operation sounds familiar so let's go to the item controller and i think we can grab this one over here so let's copy it and let's go back to the card dto and we can simply paste it over here after the cat items call and we can also change the set items into the set items gto and it's good so now instead of returning item collection and with the card dto we are returning the collection of the items details also we would like to add just the item dto between the card and item entity we have a bidirectional relationship and it would be also nice to have information about the card detail in the item detail this information will be really useful in the case when for example on the ui you would like to display only the items that are not already assigned to any card and the problem here is that if the item will be added to the card and will have the reference from the card dto to the item dto and from the other way around we'll get an infinite loop during the serialization so we'll create a new dto in the dto package that will be called plain card dto and it will be a little bit different from the card dto so in the first place let's mark it with the data notation and the first field will be private long id and the second one will be string name and if we will compare our playing card dtr with the card dto we can see that we are skipping this collection of items details so thanks to that we'll avoid the infinite loop during the serialization we'll need over here the method that will convert card into the playing card so we will say public static and you would like to return the plane card dto the name of the method will be from and will accept card object as the argument in the first place you would like to create a new playing card dto object so we want to say new playing card dto and now we'll set the fields so for the playing card dto we would like to set id and we can retrieve this id from the incoming card object and the same goes for the names so we want to access the playing card dto and set the name and we can retrieve it from the cart at the end we can return our new object so we want to say return plain card dto okay so we can go back to the item dto and under the serial number field we would like to say private plane card dto with the same name also we have to adjust our from method and in the first place we would like to use the if statement and inside we would like to again use the objects class and we want to use non-null static method and inside we would like to access the item object and check if the get card will return null or not if it's not null inside we can say item dto set plan card dto and now we can use our new from method from the playing card dto class and we can pass over here the card from the item and we have to make this check because it is possible that item is not assigned to any card and if we will perform this operation when the item is not assigned to any card we'll get a null pointer exception so now we are ready to test everything and to make it easier we'll open the pom.xml and we'll add the swagger ui documentation to our project so over here in the dependencies section we want to add a new dependency entry so it will be dependency and the artifact will be spring fox boot starter from the i o spring fox and it will be version 3. we'll also click this maven and load changes button over here and we are ready to build our project so we want to go to the maven and we want to go to the light cycle and over here we will click install and i will stop the video and start again when it's done we got the build success message so now we can go to the plugins spring boot and we can say spring would run to start our application and after it will start we will open the web browser on the local host port 8080 application is up and running as i said we are on the local host port 8080 and we can access the swagger ui documentation on the path swagger dash ui index.html in the first place let's test out the crude for the item entity so we want to open item controller and we can find our methods over here so in the first place we would like to add a new item so we want to select the post try it out and over here we don't need those stuff and we'll leave only the serial number and we'll set it to s1 and we'll click execute and we can see that our object has been created so now let's change the name we need the put method over here the id of our item was one so we're going to put it over here and we'll change the serial number to the s2 i want to click execute and we can see that the serial number is different now and now let's try to use the get by id endpoint we want to open this one one over here execute and we can see it's over here let's add another item so we go over here and this time we'll add s3 and now we can get the entire collection of items we want to try it out execute and we can see that we have two entries let's delete one with the id 2. we want to go here delete and we want to put 2 over here execute the object has been returned but let's make sure so we'll open get all items end point execute and we have only one entry now let's create a card we want to open card controller and you want to go over here try it out we'll need only the name so it will be c1 it's here so let's add another one it will be c2 execute and it's here let's get all the cards right out execute and you can see there is our collection of cards let's edit the one with the id4 so we want to find the put endpoint and the id was and we want to change the name to let's say c4 execute and we can see it is the new name right now so let's go to the endpoint that allows us to retrieve the specific card by id we'll put 4 over here and we can see it is c4 now let's try to add item to the card so we'll go over here and we want to open this one and now we have to provide the card id let's add it to the one we have edited so it will be four and the item id was 1 and now let's execute it and we can see that our plain card dto is known right now which is not true because the item is already assigned to the card with the id4 so let's go back to the code and let's fix this one so our problem is located over here in the add item to card method so after checking the condition and adding item to the card we also have to set the card for the item object so we want to say item that card and we want to say cart over here so let's restart the application and we'll try it again okay here we are let's quickly create a new item and cards so we will go over here we'll add new item and it will have s1 serial number and you can see it has been created and it has id1 so now let's create cards we will have two cards we want to add them over here and it will be cart 1 execute it's over here and also cart 2 execute and it's over here so now let's add item to the card so we'll add it to the card with the id 2 and the item id was 1. we want to click execute and we can see that now everything is set correctly so let's also check if it's possible to add the same item to the different card and we'll change the card id to free we'll click execute and we can see that it is not possible because we are getting the internal server error and in the logs of our application we probably received a message that the item one is already assigned to card with the id too let's test few more things so in the first place let's return the collection of cards we can see it's correct over here we have one item for the c1 card and let's also check out the item controller and let's return the collection of items and you can see we have only one item that is assigned to c1 card let's try to remove the item from the cart so we'll go over here the card id was 2 and item id was 1. so we want to click execute we can see that now the c1 card is empty but let's make sure i will retrieve the collection of the cards and it is also empty over here okay guys so this is it this is how you want to create an api for your one-to-many relationship it was a lot of coding and also a lot of testing but of course we have also learned a lot of things i encourage you to get familiar with this code to play a little bit with the end points so you will get a better understanding how it works thank you for watching remember about subscribing to the channel and liking the videos see you next time bye
Info
Channel: CodeForgeYT
Views: 9,890
Rating: 4.9619045 out of 5
Keywords: programming, guide, tutorial, spring, boot, rest, web, service, restful, java, lombok, annotation, application, maven, h2, jpa, hibernate, relation, relationship, mapping, endpoint, jdbc, crud, api, server, swagger, ui, example, persistance, @OneToMany, collection, list, primary, key, dto, serialization, serialize, bidirectional, exception, mvn, to, database, dbms, repository, controller, path, body, json, request, response, http, entity, persist, retrieve, transactional, dependency, consuming, testing, endpoints, variable, in, memory, configuration, call
Id: eQsXQBiXXsg
Channel Id: undefined
Length: 85min 25sec (5125 seconds)
Published: Wed Nov 11 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.