Pernyataan INSERT di JPA

1. Ikhtisar

Dalam tutorial singkat ini, kita akan mempelajari cara melakukan pernyataan INSERT pada objek JPA .

Untuk informasi lebih lanjut tentang Hibernasi secara umum, lihat panduan komprehensif kami untuk JPA dengan Musim Semi dan pengenalan Data Musim Semi dengan JPA untuk mendalami topik ini.

2. Objek yang Ada di JPA

Di JPA, setiap entitas yang beralih dari status transien ke terkelola secara otomatis ditangani oleh EntityManager .

The EntityManager memeriksa apakah entitas tertentu sudah ada dan kemudian memutuskan apakah harus dimasukkan atau diperbarui. Karena manajemen otomatis ini, t ia hanya pernyataan diperbolehkan oleh JPA adalah SELECT, UPDATE dan DELETE.

Dalam contoh di bawah ini, kita akan melihat berbagai cara untuk mengelola dan melewati batasan ini.

3. Mendefinisikan Model Umum

Sekarang, mari kita mulai dengan mendefinisikan entitas sederhana yang akan kita gunakan sepanjang tutorial ini:

@Entity public class Person { @Id private Long id; private String firstName; private String lastName; // standard getters and setters, default and all-args constructors }

Juga, mari kita tentukan kelas repositori yang akan kita gunakan untuk implementasi kita:

@Repository public class PersonInsertRepository { @PersistenceContext private EntityManager entityManager; }

Selain itu, kami akan menerapkan anotasi @Transactional untuk menangani transaksi secara otomatis pada Spring. Dengan cara ini, kita tidak perlu khawatir tentang membuat transaksi dengan EntityManager kita , melakukan perubahan kita, atau melakukan rollback secara manual dalam kasus pengecualian.

4. createNativeQuery

Untuk kueri yang dibuat secara manual, kita dapat menggunakan metode EntityManager # createNativeQuery . Ini memungkinkan kita membuat semua jenis kueri SQL, tidak hanya yang didukung oleh JPA. Mari tambahkan metode baru ke kelas repositori kita:

@Transactional public void insertWithQuery(Person person) { entityManager.createNativeQuery("INSERT INTO person (id, first_name, last_name) VALUES (?,?,?)") .setParameter(1, person.getId()) .setParameter(2, person.getFirstName()) .setParameter(3, person.getLastName()) .executeUpdate(); }

Dengan pendekatan ini, kita perlu mendefinisikan kueri literal termasuk nama kolom dan mengatur nilainya yang sesuai.

Kami sekarang dapat menguji repositori kami:

@Test public void givenPersonEntity_whenInsertedTwiceWithNativeQuery_thenPersistenceExceptionExceptionIsThrown() { Person person = new Person(1L, "firstname", "lastname"); assertThatExceptionOfType(PersistenceException.class).isThrownBy(() -> { personInsertRepository.insertWithQuery(PERSON); personInsertRepository.insertWithQuery(PERSON); }); }

Dalam pengujian kami, setiap operasi mencoba memasukkan entri baru ke database kami. Karena kami mencoba memasukkan dua entitas dengan id yang sama , operasi penyisipan kedua gagal dengan menampilkan PersistenceException .

Prinsipnya di sini sama jika kita menggunakan @Query Spring Data .

5. bertahan

Dalam contoh kami sebelumnya, kami membuat kueri penyisipan, tetapi kami harus membuat kueri literal untuk setiap entitas. Pendekatan ini tidak terlalu efisien dan menghasilkan banyak kode boilerplate.

Sebagai gantinya, kita dapat menggunakan metode persist dari EntityManager .

Seperti pada contoh kita sebelumnya, mari perluas kelas repositori kita dengan metode kustom:

@Transactional public void insertWithEntityManager(Person person) { this.entityManager.persist(person); }

Sekarang, kita bisa menguji pendekatan kita lagi :

@Test public void givenPersonEntity_whenInsertedTwiceWithEntityManager_thenEntityExistsExceptionIsThrown() { assertThatExceptionOfType(EntityExistsException.class).isThrownBy(() -> { personInsertRepository.insertWithEntityManager(new Person(1L, "firstname", "lastname")); personInsertRepository.insertWithEntityManager(new Person(1L, "firstname", "lastname")); }); }

Berbeda dengan menggunakan kueri asli, kami tidak harus menentukan nama kolom dan nilai yang sesuai . Sebaliknya, EntityManager menanganinya untuk kita.

Dalam pengujian di atas, kami juga mengharapkan EntityExistsException dilempar sebagai pengganti PersistenceException superclass yang lebih terspesialisasi dan dilemparkan oleh persist .

Di sisi lain, dalam contoh ini, kita harus memastikan bahwa kita memanggil metode insert setiap kali dengan instance baru Person. Jika tidak, ini akan dikelola oleh EntityManager, menghasilkan operasi pembaruan.

6. Kesimpulan

Dalam artikel ini, kami mengilustrasikan cara untuk melakukan operasi penyisipan pada objek JPA. Kami melihat contoh penggunaan kueri asli, serta menggunakan EntityManager # persist untuk membuat pernyataan INSERT kustom.

Seperti biasa, kode lengkap yang digunakan dalam artikel ini tersedia di GitHub.