Lesplan module 01
Wat is ORM / JPA


Lesplan voor de les "Wat is ORM" uit de cursus "Introductie ORM". Dit zijn aantekeningen voor de cursusleider om alle belangrijke begrippen de revue te laten passeren.

Het doel van deze les is dat de ontwikkelaar weet waarvoor ORM gebruikt wordt, welke begrippen daarbij horen en hoe zich dat verhoudt tot Java EE. Daarnaast leert de ontwikkelaar hoe de verhouding tussen de database en Java code ligt, hoe de mapping geschiedt met annotaties en een paar simpele annotaties.

Na deze sessie kan de ontwikkelaar zich enigszins redden in een entity class.

Wat is ORM en waar zit dat in de architectuur?

Begin met tekenen van architectuurplaat:

orm architectuur diagram

Merk op:

  • verschillende lagen met elk hun verantwoordelijkheid: UI, service (business logica) en data (database opslag)

  • we hebben database technologie en Java technologie

  • ORM is de technologie die het mogelijk maakt om van Java naar database tabellen te gaan en weer terug

  • ORM leeft in de Java wereld in het blokje ORM:

  • het blokje ORM omvat:

    • DAOs voor de queries en database acties

    • Entities voor de mapping tussen database tabellen en Java objecten.

  • ORM heet in Java de Java Persistence API (JPA)

  • JPA is een standaard waarvan verschillende implementaties (varianten) van zijn

  • JPA is onderdeel van de Java Enterprise Edition standaard (Java EE)

  • Java EE is een combinatie van standaarden zoals web technologie, persistentie, caching, computer-computer communicatie (messaging) enz, en JPA is er één van.

  • Hibernate is een JPA implementatie (variant)

  • JPA, ORM en Hibernate wordt door elkaar heen gebruikt als terminologie (voor ons is Hibernate hetzelfde als JPA)

Hoe werkt ORM precies?

Houd er rekening mee dat je 3 kolommen nodig hebt op je bord:

  1. tabel

  2. UML class

  3. Java code voor class

Het liefst houd je 50% over voor de Java code.

Teken een tabel regions (uit de Introductie SQL), gebaseerd op:

CREATE TABLE regions
    ( region_id      NUMBER
      CONSTRAINT  region_id_nn NOT NULL
    , region_name    VARCHAR2(25)
    );

En teken een UML class Region met daarin de velden id en name:

stap2 class region
Note
merk op dat je zo’n Java class ook 'Entity' of 'Entiteit' noemt.

Schrijf daarnaast de Java code uit voor de Java class:

//(1)
public class Region {
    //(1)
    private Long id;

    //(1)
    private String name;

    public Long getId() {}
    public void setId(Long id) {}
    public String getName() {}
    public String setName(String name) {}
}
  1. Houd genoeg ruimte over voor het toevoegen van annotaties

Note
Vraag naar de verschillen tussen de Java code en de database. Dit zijn dus met name de naamgeving van de class versus tabel en de kolommen versus de velden.

Merk op dat ORM hier juist voor bedoeld is en dat de manier zoals wij ontwikkelen (Java first) niet de enige manier van software bouwen is (andere bedrijven doen schema first, of je erft een bestaand schema).

Werk uit hoe dit in traditioneel Java koppelt met de database:

public Region getRegionById(Long id) throws SQLException{
    try (
        Connection connection = datasource.getConnection();
        PreparedStatement ps = connection.prepareStatement(
            "SELECT region_id, region_name "
          + "FROM regions "
          + "WHERE region_id = ?");
    ) {
        ps.setParameter(1, id);
        try (ResultSet rs = ps.executeQuery();) {
            while(rs.next()) {
                Long id = rs.getLong(1);
                String name = rs.getString(2);
                Region r = new Region();
                r.setId(id);
                r.setName(name);
                return r;
            }
        }
    }
}
Note
Laat de cursisten beantwoorden welke onderdelen erg onderhoudgevoelig zijn en welke onderdelen redelijk dom werk zijn.

Merk op dat je dit voor elke entiteit moet doen, voor elke query en voor elke actie (creates, updates en deletes). Merk ook op dat je hier geen controle hebt of er slechts één record gevonden is bij de query.

De beste programmeur is een luie programmeur dus deze vlieger gaat niet op. Daarom JPA.

ORM annotaties toevoegen

Note
Vraag wat een annotatie is.

Leg nog een keer kort uit dat een annotatie een uitbreiding is op een Java class, veld, parameter of methode om extra informatie daarbij op te slaan die later weer uitgelezen kan worden door programmacode (zoals Hibernate).

Begin met het maken van een entiteit van de Region class door de @Entity annotatie toe te voegen. JPA weet nu dat deze class onder zijn regie valt en zal dus zijn magie er op los laten.

Merk op dat JPA standaard alle velden automatisch gebruikt voor de mapping tussen Java en SQL.

Note
Vraag wat er nu mis gaat

JPA weet niet welke tabel hierbij hoort. Dus de @Table annotatie toevoegen.

Note
Vraag wat er nu nog mis gaat

JPA weet niet welke kolom bij id en name hoort. Standaard wordt de veldnaam gebruikt. Voeg de @Column annotatie toe.

Note
Wat mist er nog?

De kolom "region_id" mag niet null zijn. Voeg nullable = false toe aan de column annotatie.

Er is nog iets niet goed: het id veld is niet zomaar een kolom, het is een @Id kolom. Wanneer je dit probeert te starten in Hibernate zie je dat Hibernate een foutmelding geeft dat de entiteit Region geen ID value heeft.

Note
Regel: een entiteit is een object met een ID.

De code voor het uitlezen van een Region met JPA is vrij eenvoudig:

public Region getRegionById(Long id) {
    EntityManagerFactory factory = Persistence
            .createEntityManagerFactory("persistenceUnitName");
    entityManager = factory.createEntityManager();
    return entityManager.find(Region.class, Id);
}

Vertel dat normaal gesproken de entityManager door Wildfly wordt geleverd en dat je die niet hoeft op te zoeken. De code wordt dus nog 2 regels korter.

De code voor het opslaan is ook simpel:

@PersistenceContext //(1)
private EntityManager entityManager;

public void save(Region region) {
    entityManager.persist(region);
}
  1. Zorgt ervoor dat Wildfly de entity manager injecteert in jouw object.

Merk op dat dit natuurlijk alleen werkt wanneer de applicatie binnen _Wildfly draait. Daarbuiten moet je er zelf voor zorgen.

Afsluiting

Vertel dat er nog veel meer annotaties zijn en dat je met die annotaties relaties tussen de classes kan vastleggen. Er is ook nog een heleboel te leren over het schrijven van queries met de JPA-API, en dat komt in de volgende lessen aan bod.

  • Stel controlevragen over wat is JPA, Hibernate en ORM.

  • Waarom is @Entity belangrijk?

  • Moet een database schema overeenkomen met je Java code?

Huiswerk

Laat de ontwikkelaars het opleidingsprogramma project van Github (https://github.com/topicusonderwijs/opleidingsprogramma) clonen naar hun lokale workspace. En daarna het "Intro ORM" project importeren.

  • Run de Main class uit de package orm.

  • Als het goed is werkt dit out-of-the-box en zie je onder andere een lijst van regio’s in de console voorbij gaan, naast een hoop Hibernate spam.

{"id":1,"name":"Europe"}
{"id":2,"name":"Americas"}
{"id":3,"name":"Asia"}
{"id":4,"name":"Middle East and Africa"}

« Vorige module Volgende module »