Pengonversi Atribut JPA

1. Perkenalan

Dalam artikel singkat ini, kita akan membahas penggunaan Pengonversi Atribut yang tersedia di JPA 2.1 - yang, sederhananya, memungkinkan kita untuk memetakan tipe JDBC ke kelas Java.

Kami akan menggunakan Hibernate 5 sebagai implementasi JPA kami di sini.

2. Membuat Konverter

Kami akan menunjukkan bagaimana menerapkan konverter atribut untuk kelas Java khusus.

Pertama, mari buat kelas PersonName - yang akan diubah nanti:

public class PersonName implements Serializable { private String name; private String surname; // getters and setters }

Kemudian, kami akan menambahkan atribut jenis PERSONNAME ke @ Entity class:

@Entity(name = "PersonTable") public class Person { private PersonName personName; //... }

Sekarang kita perlu membuat konverter yang mengubah atribut PersonName menjadi kolom database dan sebaliknya. Dalam kasus kami, kami akan mengonversi atribut menjadi nilai String yang berisi bidang nama dan nama belakang.

Untuk melakukannya kita harus membuat anotasi kelas konverter kita dengan @Converter dan mengimplementasikan antarmuka AttributeConverter . Kami akan membuat parameter antarmuka dengan jenis kelas dan kolom database, dalam urutan itu:

@Converter public class PersonNameConverter implements AttributeConverter { private static final String SEPARATOR = ", "; @Override public String convertToDatabaseColumn(PersonName personName) { if (personName == null) { return null; } StringBuilder sb = new StringBuilder(); if (personName.getSurname() != null && !personName.getSurname() .isEmpty()) { sb.append(personName.getSurname()); sb.append(SEPARATOR); } if (personName.getName() != null && !personName.getName().isEmpty()) { sb.append(personName.getName()); } return sb.toString(); } @Override public PersonName convertToEntityAttribute(String dbPersonName) { if (dbPersonName == null || dbPersonName.isEmpty()) { return null; } String[] pieces = dbPersonName.split(SEPARATOR); if (pieces == null || pieces.length == 0) { return null; } PersonName personName = new PersonName(); String firstPiece = !pieces[0].isEmpty() ? pieces[0] : null; if (dbPersonName.contains(SEPARATOR)) { personName.setSurname(firstPiece); if (pieces.length >= 2 && pieces[1] != null && !pieces[1].isEmpty()) { personName.setName(pieces[1]); } } else { personName.setName(firstPiece); } return personName; } }

Perhatikan bahwa kami harus menerapkan 2 metode: convertToDatabaseColumn () dan convertToEntityAttribute ().

Kedua metode tersebut digunakan untuk mengkonversi dari atribut ke kolom database dan sebaliknya.

3. Menggunakan Konverter

Untuk menggunakan konverter kita, kita hanya perlu menambahkan anotasi @Convert ke atribut dan menentukan kelas konverter yang ingin kita gunakan :

@Entity(name = "PersonTable") public class Person { @Convert(converter = PersonNameConverter.class) private PersonName personName; // ... }

Terakhir, mari buat pengujian unit untuk melihat bahwa pengujian tersebut benar-benar berfungsi.

Untuk melakukannya, pertama-tama kita akan menyimpan objek Person di database kita:

@Test public void givenPersonName_whenSaving_thenNameAndSurnameConcat() { String name = "name"; String surname = "surname"; PersonName personName = new PersonName(); personName.setName(name); personName.setSurname(surname); Person person = new Person(); person.setPersonName(personName); Long id = (Long) session.save(person); session.flush(); session.clear(); }

Selanjutnya, kami akan menguji bahwa PersonName disimpan seperti yang kami tentukan di konverter - dengan mengambil bidang itu dari tabel database:

@Test public void givenPersonName_whenSaving_thenNameAndSurnameConcat() { // ... String dbPersonName = (String) session.createNativeQuery( "select p.personName from PersonTable p where p.id = :id") .setParameter("id", id) .getSingleResult(); assertEquals(surname + ", " + name, dbPersonName); }

Mari kita juga menguji apakah konversi dari nilai yang disimpan dalam database ke kelas PersonName berfungsi seperti yang ditentukan dalam konverter dengan menulis kueri yang mengambil seluruh kelas Person :

@Test public void givenPersonName_whenSaving_thenNameAndSurnameConcat() { // ... Person dbPerson = session.createNativeQuery( "select * from PersonTable p where p.id = :id", Person.class) .setParameter("id", id) .getSingleResult(); assertEquals(dbPerson.getPersonName() .getName(), name); assertEquals(dbPerson.getPersonName() .getSurname(), surname); }

4. Kesimpulan

Dalam tutorial singkat ini, kami menunjukkan bagaimana menggunakan Pengonversi Atribut yang baru diperkenalkan di JPA 2.1.

Seperti biasa, kode sumber lengkap untuk contoh tersedia di GitHub.