What is JPA?
Tags: java
Published: 2020-07-19 17:17:24

#Table of Content

* What is JPA?

* What is ORM?

* Why use JPA?

* JPA Relationship Types

* Use of EntityManager and Spring Data JPA


#What is JPA?
The Java Persistence API (JPA) is the Java standard for mapping Java objects to a relational database. 

JPA is one possible approach to ORM. Via JPA, the developer can map, store, update, and retrieve data from relational databases to Java objects and vice versa. 

JPA can be used in Java-EE and Java-SE applications. JPA is a specification and several implementations are available. 


#Objet Relational Mapping (ORM)
The Object Relational Mapping is the base of JPA, which is all about representing and accessing data in the form of plain Java Objects – called Entities. 

Hibernate, EclipseLink, and Apache OpenJPA are some of the JPA implementations, out of which, Hibernate is more popular and widely used.


#Why use JPA?
To reduce the burden of writing codes for relational object management of an enterprise application, a programmer follows the JPA Provider framework (an implementation of JPA), which allows easy interaction with the database instance. 


#JPA Relationship Types
In a relational database, the relationships between the two tables are defined by foreign keys. Typically, one table has a column that contains the primary key of another table’s row.

In JPA, we deal with entity objects that are Java representations of database tables. So we need a different way of establishing a relationship between two entities. 

JPA entity relationships define how these entities refer to each other.


##One-to-one relationships
The **@OneToOne** annotation is used to define a one-to-one relationship between two entities.

 For example, you may have a **User** entity that contains a user's name, email, and password, but you may want to maintain additional information about a user (such as age, gender, and favorite color) in a separate **UserProfile** entity. 

The **@OneToOne** annotation facilitates breaking down your data and entities this way.

The **User** class below has a single **UserProfile** instance. The **UserProfile** maps to a single **User** instance.

```java
@Entity
public class User {

	@Id
	private Integer id;

	private String email;

	private String name;

	private String password;

	@OneToOne(mappedBy = "user")
	private UserProfile profile;
	...
}
```

```java
@Entity
public class UserProfile {

	@Id
	private Integer id;

	private int age;

	private String gender;

	private String favoriteColor;

	@OneToOne
	private User user;
	...
}
```

The JPA provider uses UserProfile's user field to map **UserProfile** to User. 
The mapping is specified in the mappedBy attribute in the **@OneToOne** annotation.


## One-to-many and many-to-one relationships

The **@OneToMany** and **@ManyToOne** annotations facilitate both sides of the same relationship. 

Consider an example where a Book can have only one Author, but an Author may have many books. 

The Book entity would define a **@ManyToOne** relationship with Author and the **Author** entity would define a **@OneToMany**
relationship with Book.

```java
@Entity
public class Book {

	@Id
	private Integer id;

	private String name;

	@ManyToOne
	@JoinColumn(...)
		...

}
```

```java
@Entity
public class Author {

	@Id
	@GeneratedValue
	private Integer id;

	private String name;

	@OneToMany(mappedBy = "author")
	private List<Book> books = new ArrayList<>();
	...
}
```

In this case, the **Author** class maintains a list of all of the books written by that author, and the **Book** class maintains a reference to its single author. 

Additionally, the **@JoinColumn** specifies the name of the column in the **Book** table to store the ID of the Author.

##Many-to-many relationships

Finally, the **@ManyToMany** annotation facilitates a many-to-many relationship between entities. Here's a case where a **Book** entity has multiple Authors:

```java
@Entity
public class Book {

	@Id
	private Integer id;

	private String name;

	@ManyToMany
	@JoinTable(name = "BOOK_AUTHORS",
		joinColumns = @JoinColumn(name = "BOOK_ID"),
		inverseJoinColumns = @JoinColumn(name = "AUTHOR_ID"))
	private List<Author> authors = new ArrayList<>();
	...
}
```

```java
@Entity
public class Author {

	@Id
	@GeneratedValue
	private Integer id;

	private String name;

	@ManyToMany(mappedBy = "author")
	private List<Book> books = new ArrayList<>();
	...
}
```

In this example, we create a new table, BOOK_AUTHORS, with two columns: BOOK_ID and AUTHOR_ID. 

Using the joinColumns and inverseJoinColumns attributes tell your JPA framework how to map these classes in a many-to-many relationship. 

The **@ManyToMany** annotation in the **Author** class references the field in the **Book** class that manages the relationship; namely the Author's property.


#Use of Entity Manager and Spring Data JPA
Entity Manager is a component in JPA specifications which is a front face of the framework. Entity Manager is responsible for storing and retrieving entities.

Let’s look at a sample code below. 

```java
@Component
public class BookDao {

	@Autowired
	EntityManager entityManager;

	public void addUser(Book book) {
		entityManager.persist(book);
	}

	public void updateUser(Book book) {
		Book dbBook = entityManager.find(Book.class, book.getId());
		dbBook.setAutherName(book.getAutherName());
		entityManager.persist(dbBook);
	}

	public Book getBookById(Long id) {
		return entityManager.find(Book.class, id);
	}

	public void deleteBook(Long id) {
		Book book = entityManager.find(Book.class, id);
		entityManager.remove(book);
	}
}
```

Let’s rewrite the same CRUD example for Book table. There is no need to write the methods addUser(), updateUser(), etc.. because the methods already exist in JpaRepository interface.

```java
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
	Book save(Book book);
	Optional<Book> findById(Long id);
	void deleteById(Long id);
}
```

You don’t have to provide any implementation because Spring provides implementation at runtime. 

The methods declared in repository interfaces are called query methods. 

Based on the name, parameters, and return types of the methods, Spring knows what you want to do, and prepares actual SQL statements under the hood. 

I will show you a full project example in the next article.