1. Pengenalan
EntityManager adalah bahagian dari Java Persistence API. Terutama, ia menerapkan antaramuka pengaturcaraan dan peraturan kitaran hidup yang ditentukan oleh spesifikasi JPA 2.0.
Lebih-lebih lagi, kita dapat mengakses Persistence Context, dengan menggunakan API di EntityManager .
Dalam tutorial ini, kita akan melihat konfigurasi, jenis, dan pelbagai API EntityManager .
2. Pergantungan Maven
Pertama, kita perlu memasukkan kebergantungan Hibernate:
org.hibernate hibernate-core 5.4.0.Final
Kami juga harus memasukkan kebergantungan pemandu, bergantung pada pangkalan data yang kami gunakan:
mysql mysql-connector-java 8.0.13
Kebergantungan hibernate-core dan mysql-connector-java terdapat di Maven Central.
3. Konfigurasi
Sekarang, mari kita tunjukkan EntityManager , dengan menggunakan entiti Filem yang sesuai dengan jadual MOVIE dalam pangkalan data.
Sepanjang artikel ini, kami akan menggunakan API EntityManager untuk bekerja dengan objek Filem dalam pangkalan data.
3.1. Mendefinisikan Entiti
Mari mulakan dengan membuat entiti yang sesuai dengan jadual MOVIE, menggunakan anotasi @Entity :
@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 Fail
Apabila EntityManagerFactory dibuat, pelaksanaan kegigihan mencari fail META-INF / persistence.xml di classpath .
Fail ini mengandungi konfigurasi untuk EntityManager :
Hibernate EntityManager Demo com.baeldung.hibernate.pojo.Movie true
Untuk menjelaskan, kami menentukan unit ketekunan yang menentukan datastore asas yang dikendalikan oleh EntityManager .
Selanjutnya, kami menentukan dialek dan sifat JDBC lain dari datastore yang mendasari. Hibernate adalah pangkalan data-agnostik. Berdasarkan sifat-sifat ini, Hibernate menghubungkan dengan pangkalan data yang mendasari.
4. Container and Application Managed EntityManager
Pada dasarnya, terdapat dua jenis EntityManager : Container-Managed dan Application-Managed.
Mari kita perhatikan lebih dekat setiap jenis.
4.1. EntityManager Terurus Kontena
Di sini, bekas menyuntik EntityManager dalam komponen perusahaan kami.
Dengan kata lain, wadah membuat EntityManager dari EntityManagerFactory untuk kita:
@PersistenceContext EntityManager entityManager;
Ini juga bermaksud bahawa wadah bertanggungjawab untuk memulakan transaksi, serta melakukan atau memutarnya kembali.
Begitu juga, wadah bertanggungjawab menutup EntityManager, jadi selamat digunakantanpa pembersihan manual. Walaupun kita cuba menutup EntityManager yang dikendalikan oleh kontena , ia harus membuang IllegalStateException.
4.2. Application-Managed EntityManager
Sebaliknya, kitaran hayat EntityManager diuruskan oleh aplikasi di sini.
Sebenarnya, kami akan membuat EntityManager secara manual . Selanjutnya, kami juga akan menguruskan kitaran hidup EntityManager yang telah kami buat.
Pertama, mari buat EntityManagerFactory:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.baeldung.movie_catalog");
Untuk membuat EntityManager , kita mesti secara terang memanggil createEntityManager () di EntityManagerFactory :
public static EntityManager getEntityManager() { return emf.createEntityManager(); }
Oleh kerana kami bertanggungjawab untuk membuat instance EntityManager , kami juga bertanggungjawab untuk menutupnya . Oleh itu, kita harus menutup setiap EntityManager apabila kita sudah selesai menggunakannya.
4.3. Keselamatan Benang
The EntityManagerFactory keadaan dan, akibatnya, Hibernate ini SessionFactory contoh, adalah thread selamat . Oleh itu, sangat selamat dalam konteks serentak untuk menulis:
EntityManagerFactory emf = // fetched from somewhere EntityManager em = emf.createEntityManager();
Sebaliknya, entiti EntityManager tidak selamat untuk benang dan dimaksudkan untuk digunakan dalam persekitaran yang diuraikan oleh utas . Ini bermaksud bahawa setiap utas harus mendapatkan contohnya, bekerja dengannya, dan menutupnya pada akhir.
Apabila menggunakan EntityManager yang diuruskan aplikasi , mudah untuk membuat contoh terhad pada benang:
EntityManagerFactory emf = // fetched from somewhere EntityManager em = emf.createEntityManager(); // use it in the current thread
Walau bagaimanapun, perkara menjadi tidak intuitif apabila menggunakan EntityManager s yang dikendalikan oleh kontena . 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, kod yang digunakan dalam artikel boleh didapati di Github.