JPA w NetBeans – tutorial

Java Persistence API (JPA) jako część technologii EJB 3.0 upraszcza zapis danych obiektowych w relacyjnym modelu danych. Trwały zapis modelu aplikacji jest łatwiejszy niż przy pomocy entity beans w EJB 2.1. Używanie entity beans nie było zbyt wygodne i programiści bardzo często w zamian stosowali frameworki takie jak Hibernate, Oracle TopLink, i Java Data Objects (JDO). JPA bazuje na pomysłach grup pracujących nad tymi frameworkami.

Ten post umieściłem w kategorii Java EE. JPA jest częścią specyfikacji Enterprise JavaBeans 3.0 ale nie znaczy to, że nie można go użyć w zwykłej aplikacji SE. Opiszę tutaj właśnie taki przykład. Użyję do tego NetBeans IDE 6 wraz z biblioteką TopLink Essentials, która jest implementacją JPA wykonaną przez Oracle.

Opis czynności jest zwięzły bez zbytniego rozwodzenia się. Bystry programista po tworzonym kodzie pozna co się dzieje.

  • tworzę nowy projekt Java SE
  • upewniam się, że ma ustawioną składnię 1.5 i JDK conajmniej 1.5
  • dodaję do bibliotek projektu sterownik JDBC
  • dodaję do bibliotek projektu TopLink Essentials
  • z popup menu na projekcie New->File/Folder->Persistence->Entity Class
  • nazwa klasy Student, pakiet entity
  • klikam “Create Persistence Unit” i konfiguruję połączenie z bazą (użytkownik musi mieć prawo CREATE)
  • klikam Create i Finish
  • przy pomocy adnotacji @Table zmieniam nazwę tabeli odpowiadającej tej klasie w bazie danych
@Entity
@Table(name="STUDENCI")  //domyślnie "Student"
public class Student implements Serializable {
  • w klasie Student dodaję trzy pola i tworzę dla nich akcesory
private String name;
private String surname;
private SGroup group; // jeszcze nie utworzyłem takiej klasy
  • przy pomocy adnotacji @Column zmieniam nazwy kolumn odpowiadających polom w bazie (domyślnie miałyby takie nazwy jak pola)
@Column(name = "numer_indeksu")
@Id
private Long id;
@Column(name="imie")
private String name;
@Column(name="nazwisko")
private String surname;
@JoinColumn(name="grupa_dziekanska")
private SGroup group;
  • przy pomocy adnotacji ustalam, że group będzie się odnosić do relacji wiele do jednego
@JoinColumn(name="grupa_dziekanska")
@ManyToOne
private SGroup group;
  • tworzę akcesory dla pól: zaznaczam je i z menu Refractor->Encapsulate Fields
  • analogicznie do klasy Student tworzę nowy plik dla klasy SGroup
  • przy pomocy adnotacji @Table ustalam nazwę tabeli w bazie danych
@Entity
@Table(name="GRUPY_DZIEKANSKIE")
public class SGroup implements Serializable {
  • tworzę klasę TryInsert z metodą public static void main(String[] a)
  • w kodzie klasy z menu podręcznego Persistence->Use Entity Manager
  • automatycznie utworzy się metoda public void persist(Object object) służąca do zapisu do bazy, której kod warto prześledzić
  • w metodzie main umieszczam przykładowy kod tworzący grupę dziekańską i dodający studenta:
SGroup group = new SGroup();
group.setName("BDISK1");
tryInsert.persist (group);
Student student = new Student();
student.setId(1L);
student.setName("Jurek");
student.setSurname("Gryzipiórek");
student.setGroup(group);
tryInsert.persist(student);
  • oglądam zawartość bazy i cieszę się automatycznie utworzonymi tabelami i danymi.
  • tworzę klasę TrySelect z metodą main
  • dodaję kod wyszukujący pojedyńczego studenta po Id:
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("TryJPA1PU");
EntityManager em = emf.createEntityManager();
Long numerIndexu = 1L;
Student student = em.find(Student.class, numerIndexu);
em.close();
System.out.println("Imię:" + student.getName());
System.out.println("Nazwisko:" + student.getSurname());
  • uruchamiam i cieszę się z tego jak działa automat ;)
  • tworzę klasę TryUpdate z metodą main
  • wpisuję kod wybierający studenta o podanym numerze indeksu i zmieniający jego imię w jednej transakcji:
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("TryJPA1PU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
Long numerIndexu = 1L;
Student student = em.find(Student.class, numerIndexu);
student.setName("Jerzy");
em.persist(student);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
em.getTransaction().rollback();
} finally {
em.close();
}
  • oglądam dane w bazie
  • teraz pokażę pobieranie listy obiektów w bazie – aby było to spójne wprowadzę te obiekty w tym samym przykładzie.
  • tworzę klasę TrySelectList z metodą main
  • w metodzie main tworzę grupę i dwóch studentów:
SGroup g = new SGroup ();
g.setName("Grupa Ani");
Student s1 = new Student();
s1.setId(7L);
s1.setName("Ania");
s1.setSurname("Kowalska");
s1.setGroup(g);
Student s2 = new Student ();
s2.setId(8L);
s2.setName("Ania");
s2.setSurname("Nowak");
s2.setGroup(g);
  • zapisuję dane w jednej transakcji do bazy:
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("TryJPA1PU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
em.persist(g);
em.persist(s1);
em.persist(s2);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
em.getTransaction().rollback();
}
  • Przed klasą Student dodaję Named Query (do wyszukiwania studentów po imieniu):
@Entity
@Table (name="STUDENCI")
@NamedQueries({
@NamedQuery(
name="studentsForName",
query="SELECT s FROM Student s WHERE s.name = :studentName"
)
})
public class Student implements Serializable {
  • a w metodzie main klasy TrySelectList:
Query query = em.createNamedQuery( "studentsForName");
query.setParameter("studentName", "Ania");
List <Student> students = query.getResultList();
for (Student s : students) {
System.out.println (s.getId() + " " + s.getSurname());
}
em.close();
  • uruchamiam klasę TrySelectList i cieszę się z wyniku

W powyższym opisie poruszyłem jedynie podstawowe zagadnienia związane z JPA. Na szczególną uwagę zasługuje język zapytań JPA-QL będący potężnym narzędziem. Mimo wszystko myślę, że po przeanalizowaniu niniejszego opisu można już pisać proste aplikacje z użyciem JPA.

Zacheusz Siedlecki

Komentarze

10 komentarzy do “JPA w NetBeans – tutorial”

  1. Student AGH :-P on May 26th, 2008 9:15 pm

    Acha…wiec to O TO chodzi… Dlaczego nikt TEGO nie opisal do tej pory w ten sposob? Trzy dni szarpałem sie z klikanym GUI i tutorialami dla debili wiekszych niz ja (“teraz masz juz okienko w ktorym wyswietlilismy SELECT * from MyTable, dalej juz sobie sam poradzisz”), a tu takie oswiecenie… Od siebie tylko dodam, zeby przed użyciem SUM, AVG, COUNT sobie doczytac, bo dżapakul(R) ma to zaimplementowane jakos tak dziwnie (albo jeszcze nie jestem na tym poziomie, zeby zrozumiec dlaczego wlasnie tak). Dzieki!

  2. hoook on June 4th, 2008 8:52 pm

    Powiem tak… jest to najlepsze wprowadzenie do JPA jakie czytałem, a szukam od wczoraj. Krótkie,ale treściwe. Jest wszystko, by zaczynać od podstaw.
    WIELKIE DZIĘKI.

  3. SZZ on August 10th, 2008 5:43 am

    a dla mnie te wszystkie nowe frameworki to takie debilfriendly sa, uproszenia uproszeczenia itd… kiedyś był PHP i JS i czlowiek wiedzial na czym stoi a teraz api za api za api i to jest ewolucja? chyba powrót do kart drukowanych

  4. maliniak on October 30th, 2008 11:00 pm

    mała wskazówka. jeżeli dostajemy classnotfoundexception, trzeba przebudować cały projekt. przy tworzeniu enititymanagera class loader ładuje klasy wylistowane w persitence.xml, a jeżeli nigdzie nie są używane w kodzie, to nie będą też skompilowane, stąd ten błąd.

  5. pawel on January 21st, 2010 4:18 pm

    Dzięki, właśnie czegoś takiego szukałem :). Bardzo szybko można załapać o co chodzi, a reszte da się samemu doczytać.
    Pozdrawiam

  6. rdc on March 24th, 2010 9:54 am

    Ekstra :) a teraz poproszę o jedną radę :) taki przykład zmienia się adres serwera z bazą danych. I co wtedy? Bo owszem można przebudować projekt z nowym adresem ale takim radom dziękujemy :) wole rozwiązanie takie, że dane dotyczące połączenia leżą sobie w pliku konfiguracyjnym. Zmienia się adres odpalam aplikację, menu konfiguracja tej aplikacji, poprawiam adres zapisuje i przy następnych uruchomieniach już działa. W ten sposób może się zmieniać adres serwera, nazwa użytkownika z dostępem do db, hasło i td :) a ja nie muszę nic przebudowywać tylko sobie konfiguruję aplikację. Wiem jak to zrobić kiedy tworzy się to w sposób tradycyjny :) tylko trzeba się narobić jak się w trakcie pracy baza powiększy np o tabele lub dwie :) a w netbeans z toplik essentials raz dwa :) tyle, że to połączenie z bazą danych jest na sztywno :( albo po prosu nie wiem jak się do niego dobrać jakąś sprytną metodą żeby np adres serwera pobierała z pliku np. ktoś wie albo ma pomysł jak to rozwiązać?

  7. Kamil on April 7th, 2010 11:13 pm

    W moim odczuciu jest to jeden z lepszych wstępów do JPA. W polskojęzycznej literaturze nadaremno szukać bardziej rzeczowego materiału.
    Ze swojej strony mogę jedynie podziękować i prosić autora o więcej tego typu tekstów.
    Pozdrawiam

  8. Zacheusz Siedlecki on April 8th, 2010 3:54 pm

    @rdc: zajrzyj do META-INF\persistence.xml tam jest dokładnie to czego potrzebujesz. To jest plik konfiguracyjny wygenerowany przez IDE który można zmieniać samodzielnie.

  9. Robert on July 4th, 2011 5:52 pm

    Dzień dobry

    Bazując na Pana artykule (super zredagowany !!!) napisałem projekt który utrwala dane z xml-a w kilkudziesięciu rozbudowanych tabelach MSSQL.
    Wszystko działało ok do chwili gdy w xml-u doszła następująca encja:
    wartosc
    Nie wiem jakich adnotacji użyć aby poprawnie utrwalić ją w BD
    Byłbym wdzięczny za pomoc
    Robert D

  10. Kamil on October 13th, 2013 10:36 am

    Na początek jest git. Dobre krótkie przykłady – szybko się czyta i samemu sprawdza. Wielkie dzięki za podzielenie się wiedzą i za chęć opisanina tego

Chcesz coś napisać?





*