Panduan untuk Hibernate EntityManager

1. Perkenalan

EntityManager adalah bagian dari Java Persistence API. Terutama, ini mengimplementasikan antarmuka pemrograman dan aturan siklus hidup yang ditentukan oleh spesifikasi JPA 2.0.

Selain itu, kita dapat mengakses Persistence Context, dengan menggunakan API di EntityManager .

Dalam tutorial ini, kita akan melihat konfigurasi, jenis, dan berbagai API dari EntityManager .

2. Ketergantungan Maven

Pertama, kita perlu memasukkan dependensi Hibernate:

 org.hibernate hibernate-core 5.4.0.Final  

Kami juga harus menyertakan dependensi driver, tergantung pada database yang kami gunakan:

 mysql mysql-connector-java 8.0.13 

Dependensi hibernate-core dan mysql-connector-java tersedia di Maven Central.

3. Konfigurasi

Sekarang, mari kita peragakan EntityManager , dengan menggunakan entitas Film yang sesuai dengan tabel MOVIE di database.

Selama artikel ini, kita akan menggunakan API EntityManager untuk bekerja dengan objek Film di database.

3.1. Mendefinisikan Entitas

Mari kita mulai dengan menciptakan entitas sesuai dengan tabel MOVIE, menggunakan @ Entity penjelasan:

@Entity @Table(name = "MOVIE") public class Movie { @Id private Long id; private String movieName; private Integer releaseYear; private String language; // standard constructor, getters, setters }

3.2. The persistence.xml Berkas

Ketika EntityManagerFactory dibuat, implementasi ketekunan mencari file META-INF / persistence.xml di classpath .

File ini berisi konfigurasi untuk EntityManager :

 Hibernate EntityManager Demo com.baeldung.hibernate.pojo.Movie true         

Untuk menjelaskannya, kami mendefinisikan persistence-unit yang menentukan datastore dasar yang dikelola oleh EntityManager .

Selanjutnya, kami mendefinisikan dialek dan properti JDBC lainnya dari datastore yang mendasarinya. Hibernate adalah database-agnostik. Berdasarkan properti ini, Hibernate terhubung dengan database yang mendasarinya.

4. Container dan Application Managed EntityManager

Pada dasarnya, ada dua jenis EntityManager : Container-Managed dan Application-Managed.

Mari kita lihat lebih dekat setiap jenisnya.

4.1. EntityManager yang Dikelola Penampung

Di sini, penampung memasukkan EntityManager di komponen perusahaan kita.

Dengan kata lain, container membuat EntityManager dari EntityManagerFactory untuk kita:

@PersistenceContext EntityManager entityManager; 

Ini juga berarti penampung bertanggung jawab untuk memulai transaksi, serta melakukan atau menggulirkannya kembali.

Demikian pula, penampung bertanggung jawab untuk menutup EntityManager, jadi aman digunakantanpa pembersihan manual. Bahkan jika kita mencoba menutup EntityManager yang dikelola container , itu harus memunculkan IllegalStateException.

4.2. EntityManager yang Dikelola Aplikasi

Sebaliknya, siklus hidup EntityManager dikelola oleh aplikasi di sini.

Faktanya, kami akan membuat EntityManager secara manual . Selain itu, kami juga akan mengelola siklus hidup EntityManager yang telah kami buat.

Pertama, mari buat EntityManagerFactory:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.baeldung.movie_catalog");

Untuk membuat EntityManager , kita harus secara eksplisit memanggil createEntityManager () di EntityManagerFactory :

public static EntityManager getEntityManager() { return emf.createEntityManager(); }

Karena kami bertanggung jawab untuk membuat instance EntityManager , kami juga bertanggung jawab untuk menutupnya . Oleh karena itu, kita harus menutup setiap EntityManager setelah selesai menggunakannya.

4.3. Keamanan Benang

The EntityManagerFactory contoh dan, akibatnya, Hibernate SessionFactory contoh, adalah benang-aman . Jadi sangat aman dalam konteks bersamaan untuk menulis:

EntityManagerFactory emf = // fetched from somewhere EntityManager em = emf.createEntityManager();

Di sisi lain, para EntityManager contoh tidak benang-aman dan dimaksudkan untuk digunakan dalam lingkungan benang-terbatas . Ini berarti bahwa setiap utas harus mendapatkan instansinya, bekerja dengannya, dan menutupnya di akhir.

Saat menggunakan EntityManager yang dikelola aplikasi , mudah untuk membuat instance dengan thread terbatas:

EntityManagerFactory emf = // fetched from somewhere EntityManager em = emf.createEntityManager(); // use it in the current thread

Namun, hal-hal menjadi kontra-intuitif saat menggunakan EntityManager yang dikelola container . Sebagai contoh:

@Service public class MovieService { @PersistenceContext // or even @Autowired private EntityManager entityManager; // omitted }

It seems that one EntityManager instance should be shared for all operations. However, the container (JakartaEE or Spring) injects a special proxy instead of a simple EntityManager here. Spring, for example, injects a proxy of type SharedEntityManagerCreator.

Every time we use the injected EntityManager, this proxy will either reuse the existing EntityManager or create a new one. Reuse usually occurs when we enable something like Open Session/EntityManager in View.

Either way, the container ensures that each EntityManager is confined to one thread.

5. Hibernate Entity Operations

The EntityManager API provides a collection of methods. We can interact with the database, by making use of these methods.

5.1. Persisting Entities

In order to have an object associated with the EntityManager, we can make use of the persist() method :

public void saveMovie() { EntityManager em = getEntityManager(); em.getTransaction().begin(); Movie movie = new Movie(); movie.setId(1L); movie.setMovieName("The Godfather"); movie.setReleaseYear(1972); movie.setLanguage("English"); em.persist(movie); em.getTransaction().commit(); }

Once the object is saved in the database, it is in the persistent state.

5.2. Loading Entities

For the purpose of retrieving an object from the database, we can use the find() method.

Here, the method searches by the primary key. In fact, the method expects the entity class type and the primary key:

public Movie getMovie(Long movieId) { EntityManager em = getEntityManager(); Movie movie = em.find(Movie.class, new Long(movieId)); em.detach(movie); return movie; }

However, if we just need the reference to the entity, we can use the getReference() method instead. In effect, it returns a proxy to the entity:

Movie movieRef = em.getReference(Movie.class, new Long(movieId));

5.3. Detaching Entities

In the event that we need to detach an entity from the persistence context, we can use the detach() method. We pass the object to be detached as the parameter to the method:

em.detach(movie);

Once the entity is detached from the persistence context, it will be in the detached state.

5.4. Merging Entities

In practice, many applications require entity modification across multiple transactions. For example, we may want to retrieve an entity in one transaction for rendering to the UI. Then, another transaction will bring in the changes made in the UI.

We can make use of the merge() method, for such situations. The merge method helps to bring in the modifications made to the detached entity, in the managed entity, if any:

public void mergeMovie() { EntityManager em = getEntityManager(); Movie movie = getMovie(1L); em.detach(movie); movie.setLanguage("Italian"); em.getTransaction().begin(); em.merge(movie); em.getTransaction().commit(); }

5.5. Querying for Entities

Furthermore, we can make use of JPQL to query for entities. We'll invoke getResultList() to execute them.

Of course, we can use the getSingleResult(), if the query returns just a single object:

public List queryForMovies() { EntityManager em = getEntityManager(); List movies = em.createQuery("SELECT movie from Movie movie where movie.language = ?1") .setParameter(1, "English") .getResultList(); return movies; }

5.6. Removing Entities

Additionally, we can remove an entity from the database using the remove() method. It's important to note that, the object is not detached, but removed.

Here, the state of the entity changes from persistent to new:

public void removeMovie() { EntityManager em = HibernateOperations.getEntityManager(); em.getTransaction().begin(); Movie movie = em.find(Movie.class, new Long(1L)); em.remove(movie); em.getTransaction().commit(); }

6. Conclusion

In this article, we have explored the EntityManager in Hibernate. We've looked at the types and configuration, and we learned about the various methods available in the API for working with the persistence context.

Seperti biasa, kode yang digunakan dalam artikel tersedia di Github.