What is JPA? Introduction to Java persistence
As a specification, the Jakarta Persistence API (formerly Java Persistence API) is concerned with persistence, which loosely means any mechanism by which Java objects outlive the application process that created them. Not all Java objects need to be persisted, but most applications persist key business objects. The JPA specification lets you define which objects should be persisted, and how they are persisted in your Java applications.
By itself, JPA is not a tool or framework; rather, it defines a set of concepts that guide implementers. While JPA’s object-relational mapping (ORM) model was originally based on Hibernate, it has since evolved. Likewise, while JPA was originally intended for use with relational databases, some JPA implementations have been extended for use with NoSQL datastores. A popular framework that supports JPA with NoSQL is EclipseLink, the reference implementation for JPA 3.
The core idea behind JPA as opposed to JDBC, is that for the most part, JPA lets you avoid the need to “think relationally.» In JPA, you define your persistence rules in the realm of Java code and objects, whereas JDBC requires you to manually translate from code to relational tables and back again.
JPA 3 in Jakarta EE
The Java Persistence API was first released as a subset of the Enterprise JavaBeans 3.0 specification (JSR 220) in Java EE 5. It has since evolved as its own spec, starting with the release of JPA 2.0 in Java EE 6 (JSR 317). JPA was adopted as an independent project of Jakarta EE in 2019. The current release as of this writing is JPA 3.1.
Popular JPA implementations like Hibernate and EclipseLink now support JPA 3. Migrating from JPA 2 to JPA 3 involves some namespace changes, but otherwise the changes are under-the-hood performance gains.
JPA and Hibernate
Because of their intertwined history, Hibernate and JPA are frequently conflated. However, like the Java Servlet specification, JPA has spawned many compatible tools and frameworks. Hibernate is just one of many JPA tools.
Developed by Gavin King and first released in early 2002, Hibernate is an ORM library for Java. King developed Hibernate as an alternative to entity beans for persistence. The framework was so popular, and so needed at the time, that many of its ideas were adopted and codified in the first JPA specification.
Today, Hibernate ORM is one of the most mature JPA implementations, and still a popular option for ORM in Java. The latest release as of this writing, Hibernate ORM 6, implements JPA 2.2. Additional Hibernate tools include Hibernate Search, Hibernate Validator, and Hibernate OGM, which supports domain-model persistence for NoSQL.
JPA and EJB
As noted earlier, JPA was introduced as a subset of Enterprise JavaBeans (EJB) 3.0, but has since evolved as its own specification. EJB is a specification with a different focus from JPA, and is implemented in an EJB container. Each EJB container includes a persistence layer, which is defined by the JPA specification.
What is Java ORM?
While they differ in execution, every JPA implementation provides some kind of ORM layer. In order to understand JPA and JPA-compatible tools, you need to have a good grasp on ORM.
Object-relational mapping is a task–one that developers have good reason to avoid doing manually. A framework like Hibernate ORM or EclipseLink codifies that task into a library or framework, an ORM layer. As part of the application architecture, the ORM layer is responsible for managing the conversion of software objects to interact with the tables and columns in a relational database. In Java, the ORM layer converts Java classes and objects so that they can be stored and managed in a relational database.
By default, the name of the object being persisted becomes the name of the table, and fields become columns. Once the table is set up, each table row corresponds to an object in the application. Object mapping is configurable, but defaults tend to work, and by sticking with defaults, you avoid having to maintain configuration metadata.
JPA with NoSQL
Until fairly recently, non-relational databases were uncommon curiosities. The NoSQL movement changed all that, and now a variety of NoSQL databases are available to Java developers. Some JPA implementations have evolved to embrace NoSQL, including Hibernate OGM and EclipseLink.
Figure 1 illustrates the role of JPA and the ORM layer in application development.
Configuring the Java ORM layer
When you set up a new project to use JPA, you will need to configure the datastore and JPA provider. You’ll configure a datastore connector to connect to your chosen database (SQL or NoSQL). You’ll also include and configure the JPA provider, which is a framework such as Hibernate or EclipseLink. While you can configure JPA manually, many developers choose to use Spring’s out-of-the-box support. We’ll take a look at both manual and Spring-based JPA installation and setup shortly.
Java Data Objects
Java Data Objects (JDO) is a standardized persistence framework that differs from JPA primarily by supporting persistence logic in the object, and by its longstanding support for working with non-relational data stores. JPA and JDO are similar enough that JDO providers frequently also support JPA. See the Apache JDO Project to learn more about JDO in relation to other persistence standards like JPA and JDBC.
Data persistence in Java
From a programming perspective, the ORM layer is an adapter layer: it adapts the language of object graphs to the language of SQL and relational tables. The ORM layer allows object-oriented developers to build software that persists data without ever leaving the object-oriented paradigm.
When you use JPA, you create a map from the datastore to your application’s data model objects. Instead of defining how objects are saved and retrieved, you define the mapping between objects and your database, then invoke JPA to persist them. If you’re using a relational database, much of the actual connection between your application code and the database will then be handled by JDBC.
As a specification, JPA provides metadata annotations, which you use to define the mapping between objects and the database. Each JPA implementation provides its own engine for JPA annotations. The JPA spec also provides the PersistanceManager or EntityManager , which are the key points of contact with the JPA system (wherein your business logic code tells the system what to do with the mapped objects).
To make all of this more concrete, consider Listing 1, which is a simple data class for modeling a musician.
Listing 1. A simple data class in Java
public class Musician < private Long id; private String name; private Instrument mainInstrument; private ArrayList performances = new ArrayList(); public Musician( Long id, String name)< /* constructor setters. */ >public void setName(String name) < this.name = name; >public String getName() < return this.name; >public void setMainInstrument(Instrument instr) < this.instrument = instr; >public Instrument getMainInstrument() < return this.instrument; >// . Other getters and setters. >
The Musician class in Listing 1 is used to hold data. It can contain primitive data such as the name field. It can also hold relations to other classes such as mainInstrument and performances .
Musician ‘s reason for being is to contain data. This type of class is sometimes known as a DTO, or data transfer object. DTOs are a common feature of software development. While they hold many kinds of data, they do not contain any business logic. Persisting data objects is a ubiquitous challenge in software development.
Data persistence with JDBC
One way to save an instance of the Musician class to a relational database would be to use the JDBC library. JDBC is a layer of abstraction that lets an application issue SQL commands without thinking about the underlying database implementation.
Listing 2 shows how you could persist the Musician class using JDBC.
Listing 2. JDBC inserting a record
Musician georgeHarrison = new Musician(0, "George Harrison"); String myDriver = "org.gjt.mm.mysql.Driver"; String myUrl = "jdbc:mysql://localhost/test"; Class.forName(myDriver); Connection conn = DriverManager.getConnection(myUrl, "root", ""); String query = " insert into users (id, name) values (?, ?)"; PreparedStatement preparedStmt = conn.prepareStatement(query); preparedStmt.setInt (1, 0); preparedStmt.setString (2, "George Harrison"); preparedStmt.setString (2, "Rubble"); preparedStmt.execute(); conn.close(); // Error handling removed for brevity
The code in Listing 2 is fairly self-documenting. The georgeHarrison object could come from anywhere (front-end submit, external service, etc.), and has its ID and name fields set. The fields on the object are then used to supply the values of an SQL insert statement. (The PreparedStatement class is part of JDBC, offering a way to safely apply values to an SQL query.)
While JDBC provides the control that comes with manual configuration, it is cumbersome compared to JPA. To modify the database, you first need to create an SQL query that maps from your Java object to the tables in a relational database. You then have to modify the SQL whenever an object signature changes. With JDBC, maintaining the SQL becomes a task in itself.
Data persistence with JPA
Now consider Listing 3, where we persist the Musician class using JPA.
Listing 3. Persisting George Harrison with JPA
Musician georgeHarrison = new Musician(0, "George Harrison"); musicianManager.save(georgeHarrison);
Listing 3 replaces the manual SQL from Listing 2 with a single line, entityManager.save() , which instructs JPA to persist the object. From then on, the framework handles the SQL conversion, so you never have to leave the object-oriented paradigm.
Metadata annotations in JPA
The magic in Listing 3 is the result of a configuration, which is created using JPA’s annotations. Developers use annotations to inform JPA which objects should be persisted, and how they should be persisted.
Listing 4 shows the Musician class with a single JPA annotation.
Listing 4. JPA’s @Entity annotation
@Entity public class Musician < // ..class body >
Persistent objects are sometimes called entities. Attaching @Entity to a class like Musician informs JPA that this class and its objects should be persisted.
XML vs. annotation-based configuration
JPA also lets you use external XML files to define class metadata, instead of annotations. But why would you do that to yourself?
Configuring JPA
Like most modern frameworks, JPA embraces coding by convention (also known as convention over configuration), in which the framework provides a default configuration based on industry best practices. As one example, a class named Musician would be mapped by default to a database table called Musician.
The conventional configuration is a timesaver, and in many cases it works well enough. It is also possible to customize your JPA configuration. As an example, you could use JPA’s @Table annotation to specify the table where the Musician class should be stored.
Listing 5. JPA’s @Table annotation
@Entity @Table(name="musician") public class Musician < // ..class body >
Listing 5 tells JPA to persist the entity (the Musician class) to the Musician table.
Primary key
In JPA, the primary key is the field used to uniquely identify each object in the database. The primary key is useful for referencing and relating objects to other entities. Whenever you store an object in a table, you will also specify the field to use as its primary key.
In Listing 6, we tell JPA what field to use as Musician ‘s primary key.
Listing 6. Specifying the primary key
@Entity public class Musician < @Id private Long id;
In this case, we've used JPA's @Id annotation to specify the id field as Musician 's primary key. By default, this configuration assumes the primary key will be set by the database--for instance, when the field is set to auto-increment on the table.
JPA supports other strategies for generating an object's primary key. It also has annotations for changing individual field names. In general, JPA is flexible enough to adapt to any persistence mapping you might need.
CRUD operations
Once you've mapped a class to a database table and established its primary key, you have everything you need to create, retrieve, delete, and update that class in the database. Calling entityManager.save() will create or update the specified class, depending on whether the primary-key field is null or applies to en existing entity. Calling entityManager.remove() will delete the specified class.
Entity relationships
Simply persisting an object with a primitive field is only half the equation. JPA also lets you manage entities in relation to one another. Four kinds of entity relationships are possible in both tables and objects:
- One-to-many
- Many-to-one
- Many-to-many
- One-to-one
Each type of relationship describes how an entity relates to other entities. For example, the Musician entity could have a one-to-many relationship with Performance , an entity represented by a collection such as List or Set .
If the Musician included a Band field, the relationship between these entities could be many-to-one, implying a collection of Musician s on the single Band class. (Assuming each musician only performs in a single band.)
Собеседование по Java EE — Java Persistence API (JPA) (вопросы и ответы). Часть 1
Общие вопросы и ответы о Java Persistence API — JPA. Часть 1.
Данный раздел был скопирован из статьи хабра https://habrahabr.ru/post/265061/, т.к. там рассмотрены многие стандартные, а также более углубленные темы.
Так же можете посмотреть раздел по Hibernate (фреймворк является реализацией JPA и темы взаимосвязанные), перейдя к списку вопросов раздела EE.
к списку вопросов раздела JEE
Вопросы
1. Что такое JPA?
2. В чем её отличие JPA от Hibernate?
3. Можно ли использовать JPA c noSQl базами?
4. В чем её отличие JPA от JDO?
5. Что такое Entity?
6. Может ли Entity класс наследоваться от не Entity классов (non-entity classes)?
7. Может ли Entity класс наследоваться от других Entity классов?
8. Может ли не Entity класс наследоваться от Entity класса?
9. Может ли Entity быть абстрактным классом?
10. Какие требования JPA к Entity классам вы можете перечислить (не менее шести требований)?
11. Какие два типа элементов есть у Entity классов. Или другими словами перечислите два типа доступа (access) к элементам Entity классов.
12. Что такое атрибут Entity класса в терминологии JPA?
13. Какие типы данных допустимы в атрибутах Entity класса (полях или свойствах)?
14. Какие типы данных можно использовать в атрибутах, входящих в первичный ключ Entity класса (составной или простой), чтобы полученный первичный ключ мог использоваться для любой базы данных? А в случае автогенерируемого первичного ключа (generated primary keys)?
15. Что такое встраиваемый (Embeddable) класс?
16. Может ли встраиваемый (Embeddable) класс содержать другой встраиваемый (Embeddable) класс?
17. Может ли встраиваемый (Embeddable) класс содержать связи (relationship) с другими Entity или коллекциями Entity? Если может, то существуют ли какие-то ограничение на такие связи (relationship)?
18. Какие требования JPA устанавливает к встраиваемым (Embeddable) классам?
19. Какие типы связей (relationship) между Entity вы знаете (перечислите восемь типов, либо укажите четыре типа связей, каждую из которых можно разделить ещё на два вида)?
20. Что такое Mapped Superclass?
21. Какие три типа стратегии наследования мапинга (Inheritance Mapping Strategies) описаны в JPA?
22. Какие два типа fetch стратегии в JPA вы знаете?
23. Что такое EntityManager и какие основные его функции вы можете перечислить?
24. Какие четыре статуса жизненного цикла Entity объекта (Entity Instance’s Life Cycle) вы можете перечислить?
25. Как влияет операция persist на Entity объекты каждого из четырех статусов?
26. Как влияет операция remove на Entity объекты каждого из четырех статусов?
27. Как влияет операция merge на Entity объекты каждого из четырех статусов?
28. Как влияет операция refresh на Entity объекты каждого из четырех статусов?
29. Как влияет операция detach на Entity объекты каждого из четырех статусов?
30. Для чего нужна аннотация Basic?
31. Для чего нужна аннотация Access?
32. Какими аннотациями можно перекрыть связи (override entity relationship) или атрибуты, унаследованные от суперкласса, или заданные в embeddable классе при использовании этого embeddable класса в одном из entity классов и не перекрывать в остальных?
33. Какой аннотацией можно управлять кешированием JPA для данного Entity?
34. Какие аннотации служит для задания класса преобразования basic атрибута Entity в другой тип при сохранении/получении данных их базы (например, работать с атрибутом Entity boolean типа, но в базу сохранять его как число)?
35. Какой аннотацией можно задать класс, методы которого должен выполнится при определенных JPA операциях над данным Entity или Mapped Superclass (такие как удаление, изменение данных и т.п.)?
36. Для чего нужны callback методы в JPA? К каким сущностям применяются аннотации callback методов? Перечислите семь callback методов (или что тоже самое аннотаций callback методов)
37. Какие аннотации служить для установки порядка выдачи элементов коллекций Entity?
38. Какой аннотацей можно исключить поля и свойства Entity из маппинга (property or field is not persistent)?
40. Какие два вида кэшей (cache) вы знаете в JPA и для чего они нужны?
41. Какие есть варианты настройки second-level cache (кэша второго уровня) в JPA или что аналогично опишите какие значения может принимать элемент shared-cache-mode из persistence.xml?
42. Как можно изменить настройки fetch стратегии любых атрибутов Entity для отдельных запросов (query) или методов поиска (find), то если у Entity есть атрибут с fetchType = LAZY, но для конкретного запроса его требуется сделать EAGER или наоборот?
43. Каким способом можно в коде работать с кэшем второго уровня (удалять все или определенные Entity из кеша, узнать закэшировался ли данное Entity и т.п.)?
44. Каким способом можно получить метаданные JPA (сведения о Entity типах, Embeddable и Managed классах и т.п.)?
45. Что такое JPQL (Java Persistence query language) и чем он отличается от SQL?
46. Что означает полиморфизм (polymorphism) в запросах JPQL (Java Persistence query language) и как его «выключить»?
47. Что такое Criteria API и для чего он используется?
48. В чем разница в требованиях к Entity в Hibernate, от требований к Entity, указанных в спецификации JPA (см. вопрос 10)?
49. Какая уникальная стратегия наследования есть в Hibernate, но нет в спецификации JPA?
50. Какие основные новые возможности появились в спецификации JPA 2.1 по сравнению с JPA 2.0 (перечислите хотя бы пять-шесть новых возможностей)?
Ответы
1. Что такое JPA?
JPA (Java Persistence API) это спецификация Java EE и Java SE, описывающая систему управления сохранением java объектов в таблицы реляционных баз данных в удобном виде. Сама Java не содержит реализации JPA, однако существует много реализаций данной спецификации от разных компаний (открытых и нет). Это не единственный способ сохранения java объектов в базы данных (ORM систем), но один из самых популярных в Java мире.
2. В чем её отличие JPA от Hibernate?
Hibernate одна из самых популярных открытых реализаций последней версии спецификации (JPA 2.1). Даже скорее самая популярная, почти стандарт де-факто. То есть JPA только описывает правила и API, а Hibernate реализует эти описания, впрочем у Hibernate (как и у многих других реализаций JPA) есть дополнительные возможности, не описанные в JPA (и не переносимые на другие реализации JPA).
3. Можно ли использовать JPA c noSQl базами?
Вообще, спецификация JPA говорит только об отображении java объектов в таблицы реляционных баз данных, но при этом существует ряд реализаций данного стандарта для noSql баз данных: Kundera, DataNucleus, ObjectDB и ряд других. Естественно, при этом не все специфичные для реляционных баз данных особенности спецификации переносятся на nosql базы полностью.
4. В чем её отличие JPA от JDO?
JPA (Java Persistence API) и Java Data Objects (JDO) две спецификации сохранения java объектов в базах данных. Если JPA сконцентрирована только на реляционных базах, то JDO более общая спецификация которая описывает ORM для любых возможных баз и хранилищ. В принципе можно рассматривать JPA как специализированную на реляционных баз часть спецификации JDO, даже при том что API этих двух спецификаций не полностью совпадает. Также отличаются «разработчики» спецификаций — если JPA разрабатывается как JSR, то JDO сначала разрабатывался как JSR, теперь разрабатывается как проект Apache JDO.
5. Что такое Entity?
Entity это легковесный хранимый объект бизнес логики (persistent domain object). Основная программная сущность это entity класс, который так же может использовать дополнительные классы, которые могут использоваться как вспомогательные классы или для сохранения состояния еntity.
Как работать с базами данных на Java
Изучите основы работы с базами данных на Java, используя JDBC, JPA и Hibernate, с реальными примерами кода для быстрого старта.
Алексей Кодов
Автор статьи
9 июня 2023 в 16:31
В этой статье мы рассмотрим основы работы с базами данных на Java, основные технологии и подходы, которые используются в разработке современных приложений.
JDBC (Java Database Connectivity)
JDBC — это стандартный API, который позволяет Java-приложениям взаимодействовать с различными базами данных. JDBC предоставляет набор интерфейсов и классов, которые используются для выполнения операций с базами данных, таких как создание таблиц, вставка, выборка и обновление данных.
Пример использования JDBC:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class JdbcExample < public static void main(String[] args) < String url = "jdbc:mysql://localhost:3306/mydb"; String username = "root"; String password = "password"; try < Connection connection = DriverManager.getConnection(url, username, password); Statement statement = connection.createStatement(); statement.executeUpdate("CREATE TABLE users (id INT, name VARCHAR(50))"); statement.executeUpdate("INSERT INTO users (id, name) VALUES (1, 'John Doe')"); connection.close(); >catch (SQLException e) < e.printStackTrace(); >> >
Java-разработчик: новая работа через 11 месяцев
Получится, даже если у вас нет опыта в IT
JPA (Java Persistence API)
JPA — это спецификация Java EE, которая обеспечивает удобный и стандартизированный способ работы с базами данных на Java. JPA использует объектно-реляционное отображение (ORM) для сопоставления Java-объектов с таблицами базы данных. Это позволяет разработчикам работать с объектами и классами, а не с SQL-запросами.
Пример использования JPA:
import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class JpaExample < public static void main(String[] args) < EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-pu"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); User user = new User(); user.setId(1); user.setName("John Doe"); em.persist(user); em.getTransaction().commit(); em.close(); emf.close(); >>
Отметим, что JPA является более высокоуровневым и удобным подходом для работы с базами данных, чем JDBC. Он позволяет разработчикам сосредоточиться на бизнес-логике приложения, минимизируя написание SQL-кода.
Hibernate
Hibernate — это популярная реализация JPA, которая предоставляет дополнительные возможности и производительность для работы с базами данных на Java. Hibernate может использоваться как самостоятельная библиотека или интегрироваться с Java EE и Spring фреймворками.
Пример использования Hibernate:
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateExample < public static void main(String[] args) < Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); session.beginTransaction(); User user = new User(); user.setId(1); user.setName("John Doe"); session.save(user); session.getTransaction().commit(); session.close(); sessionFactory.close(); >>
В заключение, для работы с базами данных на Java существует несколько подходов и технологий. Выбор подхода зависит от требований и предпочтений разработчика. Начинающим же рекомендуется начать с изучения JPA и Hibernate, так как они предлагают более высокоуровневый и удобный подход для работы с базами данных.
Разница между JPA и Hibernate
Часто встает вопрос о разнице между Hibernate и JPA. Разъясним этот вопрос, чтобы помочь новичкам в Java понять, что такое JPA и Hibernate, и в чем между ними состоит разница.
В начале стоит отметить, что JPA (Java Persistence API) это спецификация, а Hibernate это реализация этой спецификации. Спецификация JPA предоставляет стандарты для ORM (Object-Relational Mapping) технологий в Java. Это означает, что JPA определяет набор правил и руководств по тому, как должен работать ORM-инструмент.
Hibernate, с другой стороны, это конкретная реализация этих правил и руководств. Hibernate не единственный ORM инструмент, который следует JPA спецификациям, есть другие, такие как EclipseLink, Apache OpenJPA и так далее.
Например, если разработчик хочет сохранить данные в базу данных, он может использовать JPA API для этого. Этот код будет работать независимо от того, какой ORM-инструмент используется в качестве JPA-провайдера, будь то Hibernate, EclipseLink или OpenJPA.
Однако Hibernate предлагает некоторые функции, которые не описаны в спецификации JPA. Эти функции доступны только при использовании Hibernate в качестве JPA-провайдера. Если разработчик хочет использовать эти дополнительные функции, он должен использовать Hibernate API, а не JPA API. В этом случае код больше не будет независимым от провайдера.
В заключение, можно сказать, что JPA и Hibernate не являются альтернативами друг другу. Скорее, они дополняют друг друга. Разработчики могут использовать JPA API для выполнения стандартных ORM-операций, и Hibernate API для выполнения дополнительных операций, которые не поддерживаются JPA.