JPA-kenmerkconverters

1. Inleiding

In dit korte artikel bespreken we het gebruik van de attribuutconversieprogramma's die beschikbaar zijn in JPA 2.1 - waarmee we simpelweg JDBC-typen kunnen toewijzen aan Java-klassen.

We gebruiken Hibernate 5 hier als onze JPA-implementatie.

2. Een converter maken

We gaan laten zien hoe u een attribuutconverter voor een aangepaste Java-klasse implementeert.

Laten we eerst een PersonName class - dat wordt later geconverteerd:

public class PersonName implementeert Serializable {private String name; private String achternaam; // getters en setters}

Vervolgens voegen we een kenmerk van het type toe PersonName aan een @Entiteit klasse:

@Entity (name = "PersonTable") openbare klasse Persoon {privé PersonName personName; // ...}

Nu moeten we een converter maken die de PersonName attribuut toe aan een databasekolom en vice versa. In ons geval converteren we het attribuut naar een Draad waarde die zowel de velden voor naam als achternaam bevat.

Om dat te doen we moeten onze conversieklasse annoteren met @Converter en implementeer het AttributeConverter koppel. We zullen de interface parametriseren met de typen klassen en de databasekolom, in die volgorde:

@Converter public class PersonNameConverter implementeert AttributeConverter {private static final String SEPARATOR = ","; @Override public String convertToDatabaseColumn (PersonName personName) {if (personName == null) {return null; } StringBuilder sb = nieuwe StringBuilder (); if (personNaam.getSachternaam ()! = null &&! personNaam.getSachter () .isEmpty ()) {sb.append (personNaam.getSachternaam ()); sb. toevoegen (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 [] stukken = dbPersonName.split (SEPARATOR); if (pieces == null || pieces.length == 0) {return null; } PersonName personName = nieuwe PersonName (); String firstPiece =! Pieces [0] .isEmpty ()? stukken [0]: null; if (dbPersonName.contains (SEPARATOR)) {personName.setS Achternaam (firstPiece); if (stuks.lengte> = 2 && stuks [1]! = null &&! stuks [1] .isEmpty ()) {personName.setName (stuks [1]); }} anders {personName.setName (firstPiece); } return personName; }}

Merk op dat we 2 methoden moesten implementeren: convertToDatabaseColumn () en convertToEntityAttribute ().

De twee methoden worden gebruikt om van het attribuut naar een databasekolom te converteren en vice versa.

3. Met behulp van de converter

Om onze converter te gebruiken, hoeven we alleen de @Converteren annotatie bij het attribuut en specificeer de converterklasse die we willen gebruiken:

@Entity (name = "PersonTable") openbare klasse Persoon {@Convert (converter = PersonNameConverter.class) privé PersonName personName; // ...}

Laten we tot slot een unit-test maken om te zien of het echt werkt.

Hiervoor slaan we eerst een Persoon object in onze database:

@Test openbare ongeldige gegevenPersonNaam_whenSaving_thenNaamAndSachternaamConcat () {Stringnaam = "naam"; String achternaam = "achternaam"; PersonName personName = nieuwe PersonName (); personName.setName (naam); personName.setSachter (achternaam); Persoon persoon = nieuwe persoon (); person.setPersonName (personName); Long id = (Long) session.save (persoon); sessie.flush (); sessie.clear (); }

Vervolgens gaan we testen of het PersonName werd opgeslagen zoals we het in de converter hebben gedefinieerd - door dat veld uit de databasetabel op te halen:

@Test openbare ongeldig gegevenPersonName_whenSaving_thenNameAndSachterConcat () {// ... String dbPersonName = (String) session.createNativeQuery ("selecteer p.personName uit PersonTable p waar p.id =: id") .setParameter ("id", id). getSingleResult (); assertEquals (achternaam + "," + naam, dbPersonName); }

Laten we ook testen of de conversie van de waarde die is opgeslagen in de database naar de PersonName class werkt zoals gedefinieerd in de converter door een query te schrijven die het geheel ophaalt Persoon klasse:

@Test openbare ongeldig gegevenPersonName_whenSaving_thenNameAndSachterConcat () {// ... Persoon dbPerson = session.createNativeQuery ("select * from PersonTable p where p.id =: id", Person.class) .setParameter ("id", id) .getSingleResult (); assertEquals (dbPerson.getPersonName () .getName (), naam); assertEquals (dbPerson.getPersonName () .getSachter (), achternaam); }

4. Conclusie

In deze korte tutorial hebben we laten zien hoe je de nieuw geïntroduceerde Attribute Converters in JPA 2.1 kunt gebruiken.

Zoals altijd is de volledige broncode voor de voorbeelden beschikbaar op GitHub.