BACK 
										
									

Hibernate Tutorial

Hibernate Pre-Requisites: Knowledge on Core Java, JDBC For Application level understanding need Spring, Springboot Database - MySQL Knowledge Hibernate JPA · JPA is a specification. · To manage relational data in Java applications. · JPA allows us to access and persist data between Java object and relational database. · JPA follows Object-Relation Mapping (ORM) tool. · Consists of interfaces. · JPA provides a runtime EntityManager API. · EntityManager API is to process database queries and transactions on the objects. · It is JPQL (Java Persistent Query Language). JPA Includes: · Java Persistence API · Object-Relational metadata · Persistence package (API) JPA Architecture · To store business entities as relational entities. · Demonstrates to define a POJO (entity). · TO manage entities with relation. · javax persistence package. Before JDK17 abd Spring 6: import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; Note : In case of "JDK 17 and above" or "Spring 6+" import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.Table; · you would now need to replace javax.persistence.Entity when with jakarta.persistence.Entity to resolve the jpa entity is not a managed type error · Oracle has decided to transfer the ownership, transition to the creation and usage of Jakarta EE. · In this process, naming conventions has been changed. · The "Javax" namespace (Java EE) was replaced with the "Jakarta" namespace in Jakarta EE. · Java and Spring Boot new versions have adopted Jakarta EE from JDK17 and Spring Boot v3. · So, you needed to use to jakarta.persistence.Entity. · This change impacts and usage shifted from Java EE to Jakarta EE and the package naming conventions has been updated. ORM Architecture: Hibernate: · Hibernate is a Java framework. · To simplified version of development of application to interact with the database. · Open source. · Lightweight · ORM (Object Relational Mapping) tool. · Hibernate implements the specifications of JPA (Java Persistence API) for data persistence. · ORM is to map application domain model objects to the relational database tables. JPA · JPA specification to manage the relational data in applications. · Annotations defined in a jakarta.persistence package. · JPA is an open-source API. · Providers: Oracle, Redhat, Eclipse, etc. · Products: Hibernate, EclipseLink, TopLink, MyBatis, etc. · Hibernate is the most popular ORM framework and implementation of JPA. JPA architecture consists of: · Persistence: contains static methods to obtain an EntityManagerFactory instance. · EntityManagerFactory: factory class of EntityManager which creates and manages multiple instances of EntityManager. · EntityManager interface controls the persistence operations on objects and works for the Query instance. · Entity: The entities are the persistence objects stores as a record in the database. · Persistence Unit defines a set of all entity classes. In an application, EntityManager instances manage it. The set of entity classes represents the data contained within a single data store. · EntityTransaction has a one-to-one relationship with the EntityManager class. For each EntityManager, operations are maintained by EntityTransaction class. · Query is an interface that is implemented by each JPA to obtain relation objects which meet the criteria. JPA Entity Class Consists of: · Defining a JPA Entity Class · Requirements for Entity Classes · Persistent Fields and Properties in Entity Classes · Persistent Fields · Persistent Properties · Using Collections in Entity Fields and Properties · Primary Keys in Entities · Relationship Mapping · Cascade Operations and Relationships · Orphan Removal in Relationships · Embeddable Classes in Entities 1. Defining a JPA Entity Class · An entity is a lightweight. · It is a persistence domain object. · Entity denotes a table in a relational database. · Each entity instance corresponds to a row in that table. · JPA entity class is a POJO (Plain Old Java Object) class. · Similar like serializable class having ability to be serialized. Example: @Entity public class Student { private int studentID; private String studentFirstName; private String studentLastName; public Student() {} public Student(int id, String fname, String lname) { this.studentID = id; this.studentFirstName = fname; this.studentLastName = lname; } } 2. Requirements for Entity Classes · @Entity annotation from jakarta.persistence.Entity. · Entity class must have a public or protected, no-argument constructor. · The class may have other constructors. · It must not be a "final" class. · Methods or instance variables must NOT be declared final. 3. Persistent Fields and Properties in Entity Classes · Java primitive types · java.lang.String · Wrappers of Java primitive types: java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.TimeStamp, User-defined serializable types, byte[], Byte[], char[], Character[] · Enumerated types · Collections of entities · Embeddable classes 4. Persistent Fields · Instance variables need to be applied to object/relational mapping annotations. · Each field is mapped to a column with the name of the field (DEFAULT). · We can provide another name through @Column (name="newColumnName"). · @Id - Identifies the unique ID of the database entry. · @GeneratedValue - Together with an ID this annotation defines the value (generated implicitly). · @Transient data will not be serialized or not saved in a database. Example: @Entity @Table(name = "student") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private int id; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; // getter and setter methods } 5. Persistent Properties · Persistent properties refer to getter and setter methods. · Properties use getter and setter methods. · Methods named after the entity class's instance variable names. · ORM (object/relational mapping) annotations for persistent properties are applied to the getter methods. · Mapping annotations cannot be applied to @Transient fields or properties. Example: @Id @GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY ) public int getStudentID() { return studentID; } public void setStudentID(int studentID) { this.studentID = studentID; } @Column(name = "first_name", nullable = false) public String getStudentFirstName() { return studentFirstName; } public void setStudentFirstName(String studentFirstName) { this.studentFirstName = studentFirstName; } @Column(name = "last_name", nullable = false) public String getStudentLastName() { return studentLastName; } public void setStudentLastName(String studentLastName) { this.studentLastName = studentLastName; } 6. Using Collections in Entity Fields and Properties: collection interfaces: · java.util.Collection · java.util.List · java.util.Set · java.util.Map Example: Set @ManyToMany(mappedBy = "courses", cascade = { CascadeType.ALL }) private Set<Student> employees = new HashSet<Student>(); Example: List: @OneToMany(mappedBy = "trainer", cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH }) private List<Course> courses; 7. Primary Keys in Entities · Every JPA entity must have a primary key. · Entity can be simple or a composite primary key. · Use the jakarta.persistence.Id annotation for representing the primary key property or field. Example: Setting up JPA Entity Simple Primary Key Field @Entity @Table(name = "student") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private int id; @Column(name = "first_name") private String firstName; // getter and setter methods } Composite primary keys: · Composite primary keys are primary keys that consist of more than one attribute. · Composite primary keys must be defined in a primary key class. · Composite primary keys are represented with o jakarta.persistence.EmbeddedId annotation. o jakarta.persistence.IdClass annotation. Example: Embeddable Composite Primary Key Class @Embeddable public class StudentPK implements Serializable { private String studentname; private long id; public StudentPK() { } public String getStudentName() { return studentname; } public void setStudentName(String name) { this.studentname = name; } public long getId() { return id; } public void setId(long id) { this.id = id; } } Example: JPA Entity With an Embedded Composite Primary Key Class @Entity public class Student implements Serializable { StudentPK primaryKey; public Student() { } @EmbeddedId public StudentPK getPrimaryKey() { return primaryKey; } public void setPrimaryKey(StudentPK pk) { primaryKey = pk; } } Note: Composite primary key can also be represented using @IdClass annotation. Example: @Entity @IdClass(ProjectId.class) public class Project { @Id int departmentId; @Id long projectId; } · If we use multiple primary key fields, JPA needs to define a special ID class that is connected to the entity class using the @IdClass annotation. · ID class reflects the primary key fields and its objects can represent primary key values: Class ProjectId { int departmentId; long projectId; } Primary key class must: · Must have public access modifier of the class or protected if property-based access. · Class should have default constructor. · Class should implement the hashCode() and equals(Object other) methods. · Class should be serializable. · Composite primary key mapped to multiple fields or properties of the entity class (or embeddable class). 8. Relationships: · JPA allows normalized tables to have a relationship between the entity classes. · JPA relationships: · @OneToOne · @OneToMany · @ManyToOne · @ManyToMany · The relationship between EntityManager and EntiyTransaction is one-to-one. · There is an EntityTransaction instance for each EntityManager operation. · The relationship between EntityManageFactory and EntiyManager is one-to-many. · It is a factory class to EntityManager instance. · The relationship between EntityManager and Query is one-to-many. · We can execute any number of queries by using an instance of EntityManager class. · The relationship between EntityManager and Entity is one-to-many. · An EntityManager instance can manage multiple Entities. 9. Operations with Cascade and Relationships · Entities use relationships with other entity (which are having dependency). · Example: an orderitem is part of an order; if the order is deleted, the orderitem also should be deleted. This is called a cascade delete relationship. (similar to on delete cascade in SQL). · jakarta.persistence.CascadeType enumerated type represents the cascade operations. Cascade operations for Entities: · ALL o All cascade operations will be applied to the parent entity's related entity. o All is equivalent to specifying cascade= {DETACH, MERGE, PERSIST, REFRESH, REMOVE} · DETACH o When parent entity is detached from the persistence context, related entity also detached. · MERGE o When parent entity is merged to persistence context, related entity also merged. · PERSIST o When parent entity is persisted to persistence context, related entity also persisted. · REFRESH o When parent entity is refreshed in the current persistence context, related entity also refreshed. · REMOVE o When parent entity is removed from the current persistence context, related entity also removed. Note: Cascade delete relationships are specified using the cascade=REMOVE element specification for @OneToOne and @OneToMany relationships. Example: @OneToMany(cascade=REMOVE, mappedBy="customer") public Set<CustomerOrder> getOrders() { return orders; } 10. Orphan Removal in Relationships · If target entity in a one-to-one or one-to-many relationship has been removed of a relationship, it is needed to cascade the remove operation to the target entity. · Such target entities are considered "orphans,". · orphanRemoval attribute can be used to specify that orphaned entities should be removed. · Example: If an order has many orderitems and one of them is removed from the order, the removed orderitem is considered an orphan. If orphanRemoval is set to true, the orderitem entity will be deleted when the orderitem is removed from the order. The orphanRemoval attribute in @OneToMany and @oneToOne takes a Boolean value (default false). Example: @OneToMany(mappedBy="customer", orphanRemoval="true") public List<CustomerOrder> getOrders() { ... } 11. Embeddable Classes in Entities · The facility of embedding one entity inside another entity is supported by JPA. · In this case they need to map to a single table. · Use @Embeddable annotation to denote a class is eligible as embeddable class and to embed. · Embedded class attributes can be overridden using the @AttributeOverrides. Example: Creating an Embeddable Class using @Embeddable. · Address class as Embeddable Class. · The advantage with embedded objects is that, reusability and mapping of two entities to the same database table. package com.example.hibernate.entity; import jakarta.persistence.Embeddable; @Embeddable public class Address { private String addressLine1; private String addressLine2; private String city; private String state; private String country; private String zipCode; public String getAddressLine1() { return addressLine1; } public void setAddressLine1(String addressLine1) { this.addressLine1 = addressLine1; } public String getAddressLine2() { return addressLine2; } public void setAddressLine2(String addressLine2) { this.addressLine2 = addressLine2; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } } Example: Embedding an Embeddable object with @Embedded · Embedding an embeddable class using the @Embedded annotation will be embedded in the same database table as the source. import jakarta.persistence.*; @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Embedded private Name name; private String email; @Embedded @AttributeOverrides(value = { @AttributeOverride(name = "addressLine1", column = @Column(name = "house_number")), @AttributeOverride(name = "addressLine2", column = @Column(name = "street")) }) private Address address; public User() { …… } public User(Name name, String email, Address address) { this.name = name; this.email = email; this.address = address; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Name getName() { return name; } public void setName(Name name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } } Hibernate Inheritance Mapping: Three types: 1) Table Per Hierarchy 2) Table Per Concrete class 3) Table Per Subclass 1. Table per Hierarchy · A single table is required to map the whole hierarchy. · An extra column (known as discriminator column) is added to identify the class, But nullable values are stored in the table. · Use the following annotation instead of xml configuration: @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn @DiscriminatorValue annotations for mapping table per hierarchy strategy @Inheritance Annotation: · Used to entity class hierarchy. · Specified on the entity class that is the root of the entity class hierarchy. · In case of @Inheritance annotation is not provided the SINGLE_TABLE mapping strategy is used. Syntax: @Inheritance @Entity @Table("name = employees") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) // Class public class Employee { …. } @DiscriminatorColumn Annotation · Used to define the discriminator column for the SINGLE_TABLE and JOINED inheritance mapping strategies. · Discriminator column are only specified in the root of an entity class hierarchy or sub-hierarchy in which a different inheritance strategy is applied. · In case of @DiscriminatorColumn annotation is not provided, and the discriminator column is required, in such case, the name of the discriminator column sets to its defaults value “DTYPE” and the discriminator type is set to DiscriminatorType.STRING. @Entity @Table("name = employees") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "employee", discriminatorType = DiscriminatorType.STRING) // Class public class Employee { ….. } @DiscriminatorValue Annotation: · Used to set the value of the discriminator column for entities of the given type. · Only be defined on a concrete entity class. · In case, if @DiscriminatorValue annotation is not mentioned and a discriminator column is used, a provider-specific function will be used to generate a value representing the entity type. · Default discriminator value is the name of the entity itself, in case of DiscriminatorType is specified as STRING. · The inheritance strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied. · It is the best practice to specify the discriminator value for each entity class in the hierarchy. @Entity @Table("name = employees") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "employee", discriminatorType = DiscriminatorType.STRING) // Class public class Employee{ ….. } Example: Creating the Employee, P_Employee, and C_Employee classes: Employee.java file: package com.example.model; import javax.persistence.Column; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; @Entity @Table(name = "Employee") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING) @DiscriminatorValue(value = "EMP") public class Employee { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private int id; @Column(name = "name") private String name; @Column(name = "age") private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } PermanentEmployee.java file: package com.example.model; import javax.persistence.Column; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @Entity @DiscriminatorValue(value = "PEMP") public class PermanentEmployee extends Employee { @Column(name = "salary") private double salary; public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } } ContractEmployee.java file: package com.example.model; import javax.persistence.Column; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @Entity @DiscriminatorValue(value = "CEMP") public class ContractEmployee extends Employee { @Column(name = "hourlyRate") private double hourlyRate; @Column(name = "duration") private double duration; public double getDuration() { return duration; } public void setDuration(double duration) { this.duration = duration; } public double getHourlyRate() { return hourlyRate; } public void setHourlyRate(double hourlyRate){ this.hourlyRate = hourlyRate; } } Discriminators as: · "EMP" will be persisted in the discriminator column belonging to the Employee class. · "PEMP" will be persisted in the discriminator column belonging to the PermanentEmployee class. · "CEMP" will be persisted in the discriminator column belonging to the ContractEmployee class. 2. Table per concrete class: · Tables are created per class. · No nullable values in the table. · Duplicate columns are created in the subclass tables. · @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) annotation in the parent class only and specifies the strategy. · @AttributeOverrides annotation in the subclasses. · @AttributeOverrides defines that parent class attributes will be overridden in this class. · In table structure, parent class table columns will be added in the subclass table. Example: @Entity @Table(name = "employees") @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public class Employee { …. } @Entity @Table(name="regularemployees") @AttributeOverrides({ @AttributeOverride(name="id", column=@Column(name="id")), @AttributeOverride(name="name", column=@Column(name="name")) }) public class RegularEmployee extends Employee{ …. } 3. Table Per Subclass using Annotation · In this, tables are created as per persistent classes but they are treated using primary and foreign key. · No duplicate column in the relation. · @Inheritance(strategy=InheritanceType.JOINED) in the parent class · @PrimaryKeyJoinColumn annotation in the subclasses. @Entity @Table(name = "employees") @Inheritance(strategy=InheritanceType.JOINED) public class Employee { …. } @Entity @Table(name="regularemployees") @PrimaryKeyJoinColumn(name="ID") public class RegularEmployee extends Employee{ …. } @Entity @Table(name="contractemployees") @PrimaryKeyJoinColumn(name="ID") public class ContractEmployee extends Employee{ … } JPA Relationships: 1. Unidirectional 2. bidirectional. · we can model them as an attribute on exactly one of the associated entities or both. · Defining the direction of the relationship between entities has no impact on the database mapping. · It only defines the directions in which we use that relationship in our domain model. · @JoinColumn annotation is to specify the column for joining an entity association or element collection. · Whereas mappedBy attribute is used to define the referencing side of the relationship. · Bidirectional relationship, define: o the owning side o inverse or the referencing side Example: An Employee can have many emails in which Employee and Email are two entities. @JoinColumn Annotation · In a One-to-Many/Many-to-One relationship o the owning side is usually defined on the many side of the relationship (Which usually the side that owns the foreign key). · The @JoinColumn annotation defines that actual physical mapping on the owning side: @Entity public class Email { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "employee_id") private Employee employee; // ... } · Email entity will have a foreign key column named employee_id is a primary attribute of Employee entity. mappedBy Attribute · To make association bidirectional, define the referencing side. · Referencing side maps to the owning side. · Use the mappedBy attribute of @OneToMany annotation. Employee entity: @Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @OneToMany(fetch = FetchType.LAZY, mappedBy = "employee") private List<Email> emails; // ... } · value of mappedBy is the name of the association-mapping attribute on the owning side. · Established a bidirectional association between our Employee and Email entities. Example-1: One to One PostDetails Entity: @Entity(name = "PostDetails") @Table(name = "post_details") public class PostDetails { @Id @GeneratedValue private Long id; @Column(name = "created_on") private Date createdOn; @Column(name = "created_by") private String createdBy; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "post_id") private Post post; public PostDetails() {} public PostDetails(String createdBy) { createdOn = new Date(); this.createdBy = createdBy; } //Getters and setters omitted for brevity } POST Entity: @Entity(name = "Post") @Table(name = "post") public class Post { @Id @GeneratedValue private Long id; private String title; @OneToOne(mappedBy = "post", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) private PostDetails details; public void setDetails(PostDetails details) { if (details == null) { if (this.details != null) { this.details.setPost(null); } } else { details.setPost(this); } this.details = details; } } One to One Mapping Annotation - JPA/Hibernate Example: application.properties file: spring.datasource.url=jdbc:mysql://localhost:3306/mydb?allowPublicKeyRetreival=true spring.datasource.username=root spring.datasource.password=root spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect Student Entity: @Entity @Table public class Student { … } Attributes of Student Entity: @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private long id ; @Column private String sname; @Column private long mobilenumber; @Column private String email; @OneToOne @JoinColumn(name="address_fk") private Address address; Getters and Setters of Student Entity: public long getId() { return id; } public void setId(long id) { this.id = id; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public long getMobilenumber() { return mobilenumber; } public void setMobilenumber(long mobilenumber) { this.mobilenumber = mobilenumber; } public String getEmail() { return email; } public void setEmail(String email) { this. email = email; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } Constructors of Student Entity: public Student(long id, String sname, long mobilenumber, String email, Address address) { super(); this.id = id; this.sname = sname; this.mobilenumber = mobilenumber; this.email = email; this.address = address; } public Student() { super(); } Address Entity: @Entity @Table public class Address { …. } Attributes of Address Entity: @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private long id ; @Column private String city; @Column private String state; @Column private String country; @Column private String postalcode; Getters and Setters of Address Entity: public long getId() { return id; } public void setId(long id) { this.id = id; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getPostalcode() { return postalcode; } public void setPostalcode(String postalcode) { this.postalcode = postalcode; } Constructors of Address Entity: public Address(long id, String city, String state, String country, String postalcode) { super(); this.id = id; this.city = city; this.state = state; this.country = country; this.postalcode = postalcode; } public Address() { super(); } Student Controller: @RestController @RequestMapping("Student") public class StudentController { @Autowired private StudentServiceImpl ssl; @PostMapping ResponseEntity<Student> sendStudentWithAddressObject(@RequestBody Student student){ return new ResponseEntity<>(ssl.addStudent(student),HttpStatus.ACCEPTED); } @GetMapping List<Student> getAllStudentsWithRespectiveAddress(){ return ssl.getAllStudents(); } @GetMapping("{id}") ResponseEntity<Student> getStudentWithAddressWithId(@PathVariable long id){ return new ResponseEntity<>(ssl.getById(id),HttpStatus.OK); } @PutMapping("{id}") ResponseEntity<Student> updateStudentAndTheirRespectiveAddress(@PathVariable long id , @RequestBody Student student) { return new ResponseEntity<>(ssl.editStudent(id, student),HttpStatus.CREATED); } @DeleteMapping("{id}") String deleteById(@PathVariable long id){ ssl.deleteStudent(id); return "deleted"; } } } Address Controller: @RestController @RequestMapping("Address") public class AddressController { @Autowired private AddressServiceImpl addressService; @PostMapping ResponseEntity<Address> sendAddressObject(@RequestBody Address address) { return new ResponseEntity<>(addressService.addAddress(address), HttpStatus.ACCEPTED); } @GetMapping List<Address> getAllAddresses() { return addressService.getAllAddress(); } @GetMapping("{id}") ResponseEntity<Address> getAddressWithId(@PathVariable long id) { return new ResponseEntity<>(addressService.getById(id), HttpStatus.OK); } @PutMapping("{id}") ResponseEntity<Address> updateAddress(@PathVariable long id, @RequestBody Address address) { return new ResponseEntity<>(addressService.editAddress(id, address), HttpStatus.CREATED); } @DeleteMapping("{id}") String deleteById(@PathVariable long id) { addressService.deleteAddress(id); return "deleted"; } } AddressRepository: @Repository public interface AddressRepo extends JpaRepository<Address,Long>{ } StudentRepository: @Repository public interface StudentRepo extends JpaRepository<Student,Long>{ } AddressService Interface: public interface AddressService { Address addAddress(Address address); Address getById(long id); List<Address> getAllAddress(); Address editAddress(long id, Address address); void deleteAddress(long id); } StudentService Interface: public interface StudentService { Student addStudent(Student student); Student getById(long id); List<Student> getAllStudents(); Student editStudent(long id, Student entity); void deleteStudent(long id); } AddressServiceImpl: @Service public class AddressServiceImpl implements AddressService{ @Autowired private AddressRepo ar; @Override public Address addAddress(Address address) { return ar.save(address); } @Override public Address getById(long id) { Optional<Address> op=ar.findById(id); if(op.isPresent()){ return op.get(); } return null; } @Override public List<Address> getAllAddress() { return ar.findAll(); } @Override public Address editAddress(long id, Address address) { Optional<Address> op=ar.findById(id); if(op.isPresent()){ op.get().setCity(address.getCity()); op.get().setState(address.getState()); op.get().setCountry(address.getCountry()); op.get().setPostalcode(address.getPostalcode()); return ar.save(op.get()); } return null; } @Override public void deleteAddress(long id) { ar.deleteById(id); } } StudentServiceImpl: @Service public class StudentServiceImpl implements StudentService{ @Autowired private StudentRepo sr; @Override public Student addStudent(Student student) { return sr.save(student); } @Override public Student getById(long id) { Optional<Student> op=sr.findById(id); if(op.isPresent()){ return op.get(); } return null; } @Override public List<Student> getAllStudents() { return sr.findAll(); } @Override public Student editStudent(long id, Student entity) { Optional<Student> op=sr.findById(id); if(op.isPresent()){ op.get().setSname(entity.getSname()); op.get().setMobilenumber(entity.getMobilenumber()); op.get().setEmial(entity.getEmial()); op.get().setAddress(op.get().getAddress()); return sr.save(entity); } return null; } @Override public void deleteStudent(long id) { sr.deleteById(id); } } BACK