Przygotował: Jacek Sroka. Java Persistence API

Podobne dokumenty
Java Enterprise Edition spotkanie nr 6. przygotował Jacek Sroka. Java Persistence API

Bazy danych tworzenie aplikacji bazodanowych ORM / JPA

JAVA PERSISTENCE API CZĘŚĆ 2 ASPEKTY ZAAWANSOWANE. Waldemar Korłub. Narzędzia i aplikacje Java EE KASK ETI Politechnika Gdańska

JAVA PERSISTENCE API. Wykorzystano fragmenty wykładów M. Piotrowskiego i M. Wójcika. Waldemar Korłub

ORM w Javie. Adam Michalik 2007

Wykład 8. SQL praca z tabelami 5

Nowy powiew od Słońca: EJB 3.0. Copyright Piotr Kochański & Erudis,

Programowanie obiektowe

Utrwalanie danych zastosowanie obiektowego modelu danych warstwy biznesowej do generowania schematu relacyjnej bazy danych Przykład

Podstawowe informacje o technologii Java Persistence API

Oracle PL/SQL. Paweł Rajba.

1. Model ACID. 2. Deklaratywne zarządzanie transakcjami, atrybuty transakcji. 3. Propagacja transakcji. transakcje rozproszone, propagacja kontekstu

JPA Java Persistance API

E:\DYDAKTYKA\ZAI\ZWWW\Laboratoria\L07\Java Persistence.doc 2011-lis-24, 17:0 Zaawansowane aplikacje internetowe Laboratorium Java Persistence.

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Instrukcja 5 Laboratorium z Podstaw Inżynierii Oprogramowania. Warstwy integracji z bazą danych: Wzorzec DAO Technologia ORM

Bazy danych. Dr inż. Paweł Kasprowski

Metody dostępu do danych

Hibernate. Adrian Gawor, Adam Klekotka, Piotr Kubisz. Technologie Biznesu Elektronicznego. 12 maja 2009

Dostęp do baz danych w aplikacjach Java EE

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Programowanie wielowarstwowe i komponentowe

Programowanie w języku Java. Bazy danych SQLite w Javie

Wprowadzenie db4o - podstawy db4o - technikalia Przydatne wiadomości. Wprowadzenie. db4o. Norbert Potocki. 1 czerwca Norbert Potocki db4o

Enterprise JavaBeans 3.0

Podstawowe informacje o technologii Java Persistence API - przykład

Podstawowe wykorzystanie Hibernate

Wprowadzenie do projektowania i wykorzystania baz danych Relacje

Programowanie obiektowe

Informacje wstępne Autor Zofia Kruczkiewicz Wzorce oprogramowania 4

Zaawansowane aplikacje internetowe - laboratorium

Mapowanie obiektowo-relacyjne z wykorzystaniem Hibernate

Dokumentacja do API Javy.

Współbieżność w środowisku Java

Oracle11g: Wprowadzenie do SQL

Aplikacje Internetowe. Najprostsza aplikacja. Komponenty Javy. Podstawy języka Java

Klasy abstrakcyjne, interfejsy i polimorfizm

Programowanie obiektowe

BEAN VALIDATION. Waldemar Korłub. Narzędzia i aplikacje Java EE KASK ETI Politechnika Gdańska

Zasady generowania kluczy głównych Język Java Persistence Podstawowa architektura wielowarstwowych aplikacji w oparciu o wzorce oprogramowania

Podstawy frameworka Spring

Java Persistence API (JPA)

E:\DYDAKTYKA\ZAI\ZWWW\Laboratoria\L07\Java Persistence.doc 2011-lis-24, 17:0 Zaawansowane aplikacje internetowe Laboratorium Java Persistence.

Platformy Programistyczne Podstawy języka Java

EJB 2.x oraz zmiany w standardzie dla EJB 3.0. Michał Stanek

Podejście obiektowe do relacyjnych baz danych Hibernate.

Bazy danych. Andrzej Łachwa, UJ, /15

Java Persistence API - zagadnienia zaawansowane

Post-relacyjne bazy danych

Tomasz Dobek.

Obsługa transakcji rozproszonych Java. Marek Wojciechowski, Maciej Zakrzewicz Instytut Informatyki, Politechnika Poznańska

JAVA W SUPER EXPRESOWEJ PIGUŁCE

BAZY DANYCH. Transakcje. opracowanie: Michał Lech

77. Modelowanie bazy danych rodzaje połączeń relacyjnych, pojęcie klucza obcego.

EJB 3.0 & JBoss Seam. 25 kwietnia 2007 Jacek Gerbszt 1

Tworzenie warstwy integracji i uzupełnienie wartwy prezentacji w wielowarstwowej aplikacji Przykład w środowisku Visual Web JSP

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Metody dostępu do danych

Internetowe bazy danych

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Relacje. 1. Modelowanie relacji. - siedem rodzajów relacji J2EE. - relacje jedno i wielokierunkowe, - relacje reprezentowane przez kolekcje.

Programowanie w SQL procedury i funkcje. UWAGA: Proszę nie zapominać o prefiksowaniu nazw obiektów ciągiem [OLIMP\{nr indeksu}] Funkcje użytkownika

Enkapsulacja, dziedziczenie, polimorfizm

1 Przetwarzanie transakcyjne Cechy transakcji Rozpoczęcie i zakończenie Punkty bezpieczeństwa... 3

Relacyjne bazy danych. Podstawy SQL

Paweł Rajba

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Wzorce dystrybucji i wspólbieżności autonomicznej

Plan wykładu CORBA. Cechy aplikacji rozproszonych. Aplikacje rozproszone

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Relacje. 1. Modelowanie relacji. - siedem rodzajów relacji J2EE. - relacje jedno i wielokierunkowe, - relacje reprezentowane przez kolekcje.

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Gdzie jest moja tabela?

akademia androida Składowanie danych część VI

Języki programowania wysokiego poziomu. PHP cz.4. Bazy danych

Bazy danych. Plan wykładu. Diagramy ER. Podstawy modeli relacyjnych. Podstawy modeli relacyjnych. Podstawy modeli relacyjnych

Podstawowe pojęcia dotyczące relacyjnych baz danych. mgr inż. Krzysztof Szałajko

Transakcje. (c) Instytut Informatyki Politechniki Poznańskiej

KOLEKCJE - to typy masowe,zawierające pewną liczbę jednorodnych elementów

T-SQL dla każdego / Alison Balter. Gliwice, cop Spis treści. O autorce 11. Dedykacja 12. Podziękowania 12. Wstęp 15

Programowanie obiektowe

Bazy danych wykład dziewiaty Transakcje. Konrad Zdanowski ( Uniwersytet Kardynała Stefana Bazy danych Wyszyńskiego, wykładwarszawa)

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Wykład 7: Pakiety i Interfejsy

Bazy danych 9. SQL Klucze obce Transakcje

Tworzenie tabel. Bazy danych - laboratorium, Hanna Kleban 1

Programowanie obiektowe

E.14 Bazy Danych cz. 18 SQL Funkcje, procedury składowane i wyzwalacze

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Sprawdzenie poziomu izolacji transakcji (w aktualnym połączeniu):

Autor: Joanna Karwowska

Blaski i cienie wyzwalaczy w relacyjnych bazach danych. Mgr inż. Andrzej Ptasznik

Dr Michał Tanaś(

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Monika Kruk Mariusz Grabowski. Informatyka Stosowana WFiIS, AGH 13 grudzień 2006

Java Persistence API. Class powinny być zaznaczone. Kliknij przycisk Finish.

Java. Wykład. Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ

Przykłady najlepiej wykonywać od razu na bazie i eksperymentować z nimi.

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Transkrypt:

Java Persistence API

Trwałość Serializacja o dane reprezentowane binarnie lub w XMLu o brak wyszukiwania o brak transakcji O/R mapping o zazwyczaj: klasa->tabela, obiekt->wiersz, atrybut->wartość w kolumnie oręcznie JDBC o automatycznie EclipseLink, Hibernate, Toplink, JDO można dostroić do istniejącej bazy Java Persistence API (JPA) o standard wyłapujący najlepsze pomysły z istniejących rozwiązań opojo o adnotacje (deskryptory mają większy priorytet)

Encje przykład Dostosowywanie mapowania @Entity public class Osoba { @Id @GeneratedValue private int id; private String imię; private char płeć; private String nazwisko; private String ulica; private int nrdomu; private String miasto;... @Entity(name = "PERSON") @Column(name = STATE, nullable = true, length = 255, unique = false) @GeneratedValue(strategy = GenerationType.AUTO) o SEQUENCE, TABLE, IDENTITY można adnotować atrybuty lub gettery

Encje: podstawowe informacje Encje to POJO zadnotowane javax.persistence.entity otych samych klas da się używać w całej aplikacji o encje mogą rozszerzać zarówno inne encje jak i zwykłe klasy o zwykłe klasy mogą rozszerzać encje Musi istnieć publiczny lub chroniony, bezargumentowy konstruktor Musi istnieć klucz główny javax.persistence.id o lub javax.persistence.embeddedid i javax.persistence.idclass otyp podstawowy, klasa opakowująca, java.lang.string, java.util.date (z drobnymi ograniczeniami), java.sql.date

Encje: podstawowe informacje c.d. Klasa, metody ani utrwalane atrybuty nie mogą być oznaczone jako final Utrwalane atr. powinny być private, protected lub domyślnej wid. pak. Encja może badać swój stan bezpośrednio dotykając atrybutów lub metodami get/set o z innych klas dostęp do atrybutów nie powinien być bezpośredni Atrybuty które mają nie być utrwalane w bazie danych należy zanotować javax.persistence.transient lub oznaczyć modyfikatorem transient

Typy atrybutów/właściwości typy podstawowe java.lang.string inne typy serializowalne, w tym: o klasa opakowująca o typy serializowalne zdefiniowane przez użytkownika o java.math.biginteger, java.math.bigdecimal ojava.util.date, java.util.calendar, java.sql.date, java.sql.time, java.sql.timestamp obyte[], Byte[], char[], Character[],... typy wyliczeniowe inne encje kolekcje encji otylko: Collection, Set, List, Map o ewentualnie odmiany generyczne klasy zanurzone (ang. embeddable classes)

Jak zacząć? Persistence o punkt wejściowy o czyta persistence.xml z META-INF Persistence Unit o ma nazwę i opisuje połączenie z bazą o zdefiniowane w persistence.xml o może wymieniać encje, które nadzoruje/nie nadzoruje EntityManagerFactory o reprezentuje Persistence Unit Persistence Context o zbiór encji, których utrwalanie nadzoruje Persistence Provider o w jego ramach encje mają unikatową tożsamość i reprezentują trwałe dane o kończy się razem z transakcją, chyba że typu extended EntityManager o metody pozwalające nadzorować trwałość o cache pierwszego poziomu o nie wielowątkowy

persistence.xml <?xml version="1.0" encoding="utf-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="pu1" transaction-type="resource_local"> <provider>oracle.toplink.essentials.persistenceprovider</provider> <class>start.osoba</class> <properties> <property name="toplink.jdbc.user" value="test"/> <property name="toplink.jdbc.password" value="test"/> <property name="toplink.jdbc.url" value="jdbc:derby://localhost:1527/test"/> <property name="toplink.jdbc.driver" value="org.apache.derby.jdbc.clientdriver"/> <property name="toplink.ddl-generation" value="drop-and-create-tables"/> </properties> </persistence-unit> </persistence>

Pierwszy przykład EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu1"); EntityManager em = emf.createentitymanager(); Osoba o1 = new Osoba("Ala", 'K', "Trelemorele", 1, "Gdańsk"); Osoba o2 = new Osoba("Ola", 'K', "Trelemorele", 2, "Kraków"); em.gettransaction().begin(); em.persist(o1); em.persist(o2); em.gettransaction().commit(); List<Osoba> list = em.createquery("select o from Osoba o").getresultlist(); for (Osoba akt : list) { System.out.println(akt.getImię()); em.close();

Zapytania - podstawy em.createquery(""); em.createquery("select t from Trelemorele t"); em.createquery("select o from Osoba o").getresultlist(); em.createquery("select o from Osoba o").getsingleresult(); em.find(osoba.class, osobaid); o jak złe id to null em.createquery("select o from Osoba o where o.imię =?1").setParameter(1, "Ala").getResultList(); ouwaga na SQL Injection! Osoba opoid = em.find(osoba.class, idali); Osoba opowhere = (Osoba) em.createquery("select o from Osoba o where o.imię='ala'").getsingleresult(); o opoid == opowhere

Wydzielamy adres @Embeddable public class Adres { private String ulica; private int nrdomu; private String miasto;... obiekty zanurzalne nie mają tożsamości nie będzie nowej tabeli z adresami struktura tabeli z osobą się nie zmieni @Entity public class OsobaZAdresem { @Id @GeneratedValue private int id; private String imię; private char płeć; @Embedded private Adres adres;...

Przykład EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu1"); EntityManager em = emf.createentitymanager(); Adres a1 = new Adres("Matematyków", 7, "Kraków"); OsobaZAdresem o1 = new OsobaZAdresem("Ala", 'K', a1); OsobaZAdresem o2 = new OsobaZAdresem("Ola", 'K', a1); em.gettransaction().begin(); em.persist(o1); em.persist(o2); em.gettransaction().commit(); List<OsobaZAdresem> list = em.createquery("select o from OsobaZAdresem o").getresultlist(); for (OsobaZAdresem akt : list) { System.out.print(akt.getImie()); System.out.println(" - "+akt.getadres().getulica()+" - " +akt.getadres()); em.close();

Cykl życia new nie ma persistence identity, ani nie należy do persistence context managed ma i należy detached ma i nie należy removed należy, ale ma być usunięta z bazy po wywołaniu remove() encja jest zaplanowana do usunięcia, ale usuwana dopiero przy zatwierdzaniu transakcji lub po wywołaniu flush() po merge() encja zaczyna na powrót należeć o przestać może jak zakończył się persistence context (patrz SLSB) lub została zdeserializowana o merge() zwraca nową encję, a nie przekazany parametr (chyba, że przekazaliśmy encję managed)

Dodajemy firmę @Entity public class Firma { @Id @GeneratedValue int id; private String nazwa; @Embedded private Adres adres; @OneToMany private Collection<OsobaZAdresem> pracownicy; Firma f1 = new Firma("Moja Firma", new Adres("Matematyków", 8, "Warszawa")); List<OsobaZAdresem> osoby = generujosoby(); for (OsobaZAdresem o : osoby) f1.zatrudnij(o); em.gettransaction().begin(); for (OsobaZAdresem o : osoby) em.persist(o); em.persist(f1); em.gettransaction().commit(); Firma f = (Firma) em.createquery("select f from Firma f").getsingleresult();

Związki Rodzaje związków o1-1, 1-m, n-1, n-m o jedno/dwukierunkowe o czyli 7 możliwych kombinacji! Związki dwukierunkowe mają dwie strony owning oraz inverse ostrona inverse musi się odwoływać do strony owning przy pomocy atrybutu mappedby adnotacji @OneToOne, @OneToMany oraz @ManyToMany ow dwukierunkowych związkach n-1 strona wiele jest zawsze owning i nie może posiadać atrybutu mappedby o W dwukierunkowych związkach 1-1 strona owning posiada klucz obcy o W dwukierunkowych związkach n-m każda ze stron może być owning

Związki c.d. Kaskadowość o np. @OneToOne(cascade={CascadeType.PERSIST) omożliwe elementy tablicy PERSIST, MERGE, REMOVE, REFRESH oraz ALL wskazują jakie operacje przenoszą się kaskadowo na elementy pozostające w związku o domyślnie tablica jest pusta Leniwe/Gorliwe ładowanie o ze względu na efektywność domyślnie jest FetchType.LAZY ojeżeli encje są przekazywane klientowi (datached) używamy FetchType.EAGER o fetch joins

Przykład 1-1 @Entity(name="OrderUni") public class Order implements Serializable { private int id; private String ordername; private Shipment shipment; @Id @GeneratedValue public int getid() { return id; public void setid(int id) { this.id = id; @OneToOne(cascade={CascadeType.PERSIST) public Shipment getshipment() { return shipment; Związek w bazie CREATE TABLE ORDERUNI ( ID INTEGER NOT NULL, ORDERNAME VARCHAR(255), SHIPMENT_ID INTEGER ); Specyfikacja określa zasady nazywania klucza obcego Dla wersji jednokierunkowej w Shipment nie trzeba nic zmieniać public void setshipment(shipment shipment){ this.shipment = shipment;...

Przykład 1-1 BasicConfigurator.configure(); Logger.getLogger("org").setLevel(Level.ERROR); final EntityManagerFactory emf = Persistence.createEntityManagerFactory("jee6"); final EntityManager em = emf.createentitymanager(); em.gettransaction().begin(); dosomestuff(em); System.out.println("Unidirectional One-To-One test\n"); @SuppressWarnings("unchecked") List<Order> li = em.createquery("select o FROM OrderUni o").getresultlist(); for (Order o : li) { System.out.println("Order "+o.getid()+": "+o.getordername()); System.out.println("\tShipment details: "+o.getshipment().getcity()+ +o.getshipment().getzipcode()); em.gettransaction().commit();

1-1 wersja dwukierunkowa @Entity(name="ShipmentBi") public class Shipment { private int id; private String city; private String zipcode; private Order order; @Id @GeneratedValue public int getid() { return id; public void setid(int id) { this.id = id; @OneToOne(mappedBy="shipment") public Order getorder() { return order; Przy pomocy parametru mappedby wskazujemy, który atrybut encji Order realizuje związek Reprezentacja w bazie i encja Order się nie zmieniają Trzeba pamiętać o utrzymywaniu związku między obiektami Shipment s = new Shipment(); s.setcity("austin"); s.setzipcode("78727"); Order o = new Order(); o.setordername("software Order"); o.setshipment(s); s.setorder(o); public void setorder(order order) { this.order = order;... em.persist(o);

1-m wersja dwukierunkowa @Entity(name="Employee1MBid") public class Employee { private int id; private String name; private char sex; private Company company;... @ManyToOne public Company getcompany() { return company; public void setcompany(company company) { this.company = company; @Entity(name="Company1MBid") public class Company { private int id; private String name; private Collection<Employee> employees = new ArrayList<Employee>();... @OneToMany(cascade={CascadeType.ALL fetch=fetchtype.eager, mappedby="company") public Collection<Employee> getemployees() { return employees; public void setemployees(collection<employee> employees) { this.employees = employees;

1-m wersja dwukierunkowa final EntityManagerFactory emf = Persistence.createEntityManagerFactory("jwt10"); final EntityManager em = emf.createentitymanager(); em.gettransaction().begin(); deleteall(em); dosomestuff(em); @SuppressWarnings("unchecked") List<Company> lic = em.createquery("select c FROM Company1MBid c").getresultlist(); for (Company c : lic) { System.out.println("Employees of company: "+c.getname()); for (Employee e : c.getemployees()) { System.out.println("\tName: "+e.getname()+", Sex: "+e.getsex()); System.out.println(); System.out.println(); @SuppressWarnings("unchecked") List<Employee> lie = em.createquery("select e FROM Employee1MBid e").getresultlist(); for (Employee e : lie) { Company c = e.getcompany(); System.out.println("Employee: "+e.getname()+" works for: "+c.getname()); em.gettransaction().commit();

1-m jedno vs wielokierunkowe związek jednokierunkowy CREATE TABLE COMPANY1MUNI ( ID INTEGER NOT NULL, NAME VARCHAR(255) ); CREATE TABLE COMPANY1MUNI_EMPLOYEE1MUNI ( COMPANY1MUNI_ID INTEGER NOT NULL, EMPLOYEES_ID INTEGER NOT NULL ); --po stronie wiele powinny być więzy UNIQUE CREATE TABLE EMPLOYEE1MUNI ( ID INTEGER NOT NULL, SEX CHAR(1) NOT NULL, NAME VARCHAR(255) ); związek wielokierunkowy CREATE TABLE COMPANY1MBID ( ID INTEGER NOT NULL, NAME VARCHAR(255) ); CREATE TABLE EMPLOYEE1MBID ( ID INTEGER NOT NULL, SEX CHAR(1) NOT NULL, NAME VARCHAR(255), COMPANY_ID INTEGER );

EJB-QL Złączenia GROUP BY HAVING Projekcje Podzapytania Zapytania dynamiczne Nazwane zapytania Tworzenie w zapytaniu nowych obiektów Grupowe operacje UPDATE i DELETE

Złączenia Mogą służyć do: selekcji danych, dla których spełniony jest warunek złączenia do kontrolowania gorliwego ładowania Przykłady (można też używać składni tradycyjnej): JOIN o SELECT DISTINCT c FROM Company1MUni c JOIN c.employees LEFT JOIN o SELECT DISTINCT c FROM Company1MUni c LEFT JOIN c.employees LEFT OUTER JOIN o SELECT DISTINCT c FROM Company1MUni c LEFT JOIN FETCH c.employees

Projekcje/Podzapytania Wersja dwukierunkowa SELECT e.name, c.name FROM Employee1MBid e, Company1MBid c WHERE e.company = c Wersja jednokierunkowa SELECT e.name, c.name FROM Employee1MUni e, Company1MUni c WHERE e IN (SELECT em FROM c.employees em) Albo po prostu SELECT e.name, c.name FROM Company1MUni c JOIN c.employees e

Klauzule GROUP BY i HAVING Można używać GROUP BY i HAVING SELECT e.sex, count(e) FROM Employee1MUni e GROUP BY e.sex HAVING count(e) > 0 Wynikiem jest lista krotek (tu par) obiektów @SuppressWarnings("unchecked") List<Object[]> lic1 = em.createquery("select e.sex, count(e) FROM Employee1MUni e GROUP BY e.sex HAVING count(e) > 0").getResultList(); for (Object[] o : lic1) { boolean czykobieta = (Character) o[0] == 'F'; System.out.println("Na uczelniach pracuje: "+o[1]+" "+ ((czykobieta)? "kobiet" : "mężczyzn"));

Tworzenie w zapytaniu nowych obiektów class PracFirma { String pname; String cname; public PracFirma(String name, String name2) { pname = name; cname = name2; public String tostring() { return "PracFirma("+pName+","+cName+")"; @SuppressWarnings("unchecked") List<PracFirma> li7 = em.createquery("select NEW cd.reszta.pracfirma(e.name, c.name) FROM Company1MUni c JOIN c.employees e").getresultlist(); for (PracFirma o : li7) System.out.println(o);

Zapytania dynamiczne Query q4 = em.createquery("select e FROM Employee1MUni e WHERE e.name LIKE :empname"); @SuppressWarnings("unchecked") List<Employee> lic4 = q4.setparameter("empname", "%").getresultlist(); for (Employee e : lic4) { System.out.println("Name: "+e.getname()+", Sex: "+e.getsex()+"\n"); uwaga na SQL-injection jednokrotnie przygotowywany plan zapytania

Grupowe operacje UPDATE i DELETE Operacja dotyczy encji (i wszystkich jej podklas) Operacja nie przenosi się kaskadowo na powiązane encje o np. w przykładzie 1-m w wersji jednokierunkowej zadziałają więzy dla tabeli złączeniowej Zmiany zachodzą bezpośrednio w bazie danych o obchodzone jest optymistyczne blokowanie (kolumna z wersją nie jest automatycznie uaktualniana) Persistence Context nie jest synchronizowany z wynikiem operacji o można wykonać flush() Query q = em.createquery("delete FROM RoadVehicleSingle"); q.executeupdate(); Query q = em.createquery("update RoadVehicleJoined r SET r.numpassengers = 1"); q.executeupdate();

JPA bardziej obiektowe niż EB Są hierarchie klas Jest polimorfizm JPA-QL (inaczej EJB3-QL) jest obiektowy i niezależny od platformy JPA pod strzechami jest całkiem rozbudowane, ale też dobrze przemyślany o w kryzysowych sytuacjach można zapomnieć o bazie i myśleć obiektowo o z drugiej strony zrozumienie to pierwszy krok do kontroli

Przykładowa hierarchia klas public class RoadVehicle { public enum AccelerType {PEDAL,THROTTLE; protected int id; protected int numpassengers; protected int numwheels; protected String make; protected String model; public class Motorcycle extends RoadVehicle { public final AccelerType accelertype = AccelerType.THROTTLE; public class Car extends RoadVehicle { public final AccelerType accelertype = AccelerType.PEDAL; public class Coupe extends Car { public enum BoringFactor {BORING,BORINGER,BORINGEST; private BoringFactor boringfactor; public class Roadster extends Car { public enum CoolFactor {COOL,COOLER,COOLEST; private CoolFactor coolfactor;

Reprezentacja dziedziczenia Jedna tabela dla całej hierarchii klas o sposób domyślny Złączenia Po jednej tabeli na encję o tylko dla encji konkretnych (nieabstrakcyjnych)

Jedna tabela dla całej hierarchii klas Do rozróżniania podklas używana jest descriminator column zalety: bardzo efektywny polimorfizm wady: potencjalnie dużo wartości null o nie stosować z hierarchiami zawierającymi bardzo dużo atrybutów/właściwości o nie można stosować więzów not null @Entity(name="RoadVehicleSingle") @Table(name="RoadVehicleSingle") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="DISC", discriminatortype=discriminatortype.string) @DiscriminatorValue("ROADVEHICLE") public class RoadVehicle implements Serializable { public enum AccelerType {PEDAL,THROTTLE; @Id protected int id; protected int numpassengers; protected int numwheels; protected String make; protected String model; public RoadVehicle() { id = (int) System.nanoTime();...

c.d. @Entity(name="MotorcycleSingle") @DiscriminatorValue("MOTORCYCLE") public class Motorcycle extends RoadVehicle implements Serializable { public final AccelerType accelertype = AccelerType.THROTTLE; public Motorcycle() { super(); numwheels = 2; numpassengers = 2; @Entity(name="CarSingle") @DiscriminatorValue("CAR") public class Car extends RoadVehicle implements Serializable { public final AccelerType accelertype = AccelerType.PEDAL; public Car() { super(); numwheels = 4;...

Reprezentacja hierarchii w bazie CREATE TABLE ROADVEHICLESINGLE ( DISC VARCHAR(31) NOT NULL, ID INTEGER NOT NULL, NUMPASSENGERS INTEGER NOT NULL, NUMWHEELS INTEGER NOT NULL, MAKE VARCHAR(255), MODEL VARCHAR(255), ACCELERATORTYPE INTEGER, BORINGFACTOR INTEGER, COOLFACTOR INTEGER );

Złączenia Tabela zawiera jedynie atrybuty/właściwości z definicji podklasy. zalety: sprawdza się dla hierarchii zawierających bardzo dużo atrybutów/właściwości (różnych w różnych gałęziach) wady: często są potrzebne złączenia o nie stosować dla bardzo głębokich hierarchii Co z @DiscriminatorColumn? o większość adnotacji ma domyślne wartości i można ich nie podawać o uwaga nie wszystkie implementacje dodają kolumny DTYPE do głównej klasy @Entity(name="RoadVehicleJoined") @Table(name="RoadVehicleJoined") @Inheritance(strategy=InheritanceType.JOINED) public class RoadVehicle implements Serializable { public enum AccelerType {PEDAL,THROTTLE; @Id protected int id; protected int numpassengers; protected int numwheels; protected String make; protected String model;...

Przykładowa hierarchia klas CREATE TABLE ROADVEHICLEJOINED ( ID INTEGER NOT NULL, NUMPASSENGERS INTEGER NOT NULL, NUMWHEELS INTEGER NOT NULL, MAKE VARCHAR(255), MODEL VARCHAR(255) --DTYPE ); CREATE TABLE MOTORCYCLEJOINED ( ID INTEGER NOT NULL, ACCELERATORTYPE INTEGER ); CREATE TABLE CARJOINED ( ID INTEGER NOT NULL, ACCELERATORTYPE INTEGER ); CREATE TABLE COUPEJOINED ( ID INTEGER NOT NULL, BORINGFACTOR INTEGER ); CREATE TABLE ROADSTERJOINED ( ID INTEGER NOT NULL, COOLFACTOR INTEGER );

Po jednej tabeli na encję Nie wymagane przez specyfikacje (nieobowiązkowe) Każda konkretna encja ma swoją tabelę ze wszystkimi atrybutami (bezpośrednimi i odziedziczonymi) Wszystkie konkretne encje muszą mieć taki sam klucz Trudniejszy polimorfizm (w poprzedniej metodzie wystarczyła przejrzeć jedną tabelkę i ew. dołączyć pozostałe atrybuty) @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

Inne zagadnienia dotyczące reprezentacji dziedziczenia Jeżeli encja rozszerza nie-encję używamy adnotacji @MappedSuperclass opodobne do po jednej tabeli na encję, ale mniej tabel oprzydatne w wypadku jak wiele encji współdzieli atrybuty/właściwości ow nadklasie można używać adnotacji dotyczących mapowania związków ojeżeli nadklasy nie adnotujemy to pochodzące z niej atrybuty/właściwości nie będą utrwalane Encje mogą być klasami abstrakcyjnymi opolimorfizm

Polimorfizm public class Test { @SuppressWarnings("unchecked") public static void main(final String[] args) { final EntityManagerFactory emf = Persistence.createEntityManagerFactory("jee6"); final EntityManager em = emf.createentitymanager(); em.gettransaction().begin(); Coupe c = new Coupe();...; em.persist(c); Roadster r = new Roadster();...; em.persist(r); Motorcycle m = new Motorcycle();...; em.persist(m); em.gettransaction().commit(); Query q = em.createquery("select c FROM RoadVehicleJoined c"); List<RoadVehicle> vehicles = q.getresultlist(); for (RoadVehicle rv : vehicles) System.out.println(rv.getClass().getSimpleName()+": "+rv);

Transakcje

Czemu potrzebujemy transakcji Operacje atomowe try { // Wypłata z konta A catch (Exception e) { // Nie udało się wypłacić, // więc nie kontynuujemy return; try { // Wpłata na konto B catch (Exception e) { // Nie udało się wpłacić, // więc należy zwrócić pieniądze // na konto A // Wpłata na konto A return; Problemy okod jest rozwlekły i trudny do zrozumienia. owycofywanie staje się bardziej skomplikowane, jeżeli jest więcej operacji (np. 10) otrzeba rozważyć wszystkie możliwości. A co jak zwrot pieniędzy na konto A się nie powiódł? o Taki kod trudno testować

Czemu potrzebujemy transakcji Komunikacja zdalna o Czy sieć padła przed czy po wykonaniu operacji na zdalnym serwerze? Awaria bazy danych podczas zapisu o Redundancja sprzętowa nie daje 100% pewności! Współdzielenie danych przez wielu klientów o wiele aplikacji o wielu użytkowników o problem "lost update" x = odczytajstan(kontoa); x = x+100; zapiszstan(kontoa, x); Tansakcja 1 Tansakcja 2 x = odczytajstan(kontoa); x = x+100; zapiszstan(kontoa, x);

Korzyści ze stosowania transakcji Zaawansowana kontrola współbieżności oraz obsługi błędów Własności ACID oatomicity grupa operacji jest traktowana jako jedna nierozerwalna całość i podlega semantyce wszystko albo nic automatyczne wycofywanie skutków początkowych operacji z transakcji, jeżeli później wystąpił błąd oconsistency po zakończeniu transakcji system jest w stanie spójnym, w trakcie nie musi być, bo mamy atomowość oisolation wiele transakcji współbieżnie odczytuje i modyfikuje stan bazy danych, z punktu widzenia każdej z nich innych transakcji nie ma automatyczne zarządzanie blokadami odurability modyfikacje bazy danych przetrwają awarie, np. chwilowy brak zasilania prowadzenie dziennika zmian, który umożliwia dokończenie zmian po wznowieniu pracy

Nazewnictwo obiekt/komponent transakcyjny (transactional object/component) np. enterprise bean lub MS.NET-managed component zarządca transakcji (transaction manager) koordynuje operacje obiektów transakcyjnych zasób (resource) np. baza danych lub kolejka komunikatów zarządca zasobu (resource manager) nadzoruje trwały stan zasobu zarządca transakcji i zasobu najczęściej komunikują się za pomocą interfejsu X/Open XA

Modele transakcji Płaskie transakcje o begin, commit/abort o grupowanie operacji oraz wszystko albo nic o za wycofywanie odpowiada zarządca zasobu, a nie komponent Zagnieżdżone transakcje o zadanie z rezerwacją podróży odrzewo transakcji transakcje zagnieżdżone same mogą być płaskie lub zagnieżdżone Specyfikacja nie wymaga by zarządca transakcji EJB obsługiwał transakcje zagnieżdżone

Transakcje rozproszone Możliwe scenariusze o w ramach jednej transakcji modyfikowane są różne bazy danych o w ramach jednej transakcji wykonywane są operacje na bazie danych, kolejce komunikatów oraz systemach zastanych o wiele serwerów aplikacji koordynuje w tej samej transakcji Trwałość (durability) już nie jest taka oczywista! o Wszystko co ma się stać jest najpierw zapisywane w dzienniku o 2PC

Izolacja Przypomnijmy problem "lost update" x = odczytajstan(kontoa); x = x+100; zapiszstan(kontoa, x); Tansakcja 1 Tansakcja 2 x = odczytajstan(kontoa); x = x+100; zapiszstan(kontoa, x); Potrzebne są blokady o nadużywanie może doprowadzić do zakleszczeń o blokady do czytania i pisania ospotykamy w bazach danych, systemach kontroli wersji, a nawet językach programowania (synchronizacja)

Poziomy izolacji read uncommited oduża współbieżność, dużo problemów //stan A = 100 x = odczytajstan(a); x = x+100; zapiszstan(a, x); rollback; Dirty read problem Tansakcja 1 Tansakcja 2 x = odczytajstan(a); //odczytaliśmy //niespójny stan bazy x = x+100; zapiszstan(a, x); //stan A = 300

Poziomy izolacji read uncommited oduża współbieżność, dużo problemów read commited ozabezpiecza przed dirty read o najczęściej spotykany w praktyce Unrepeatable read problem Tansakcja 1 Tansakcja 2 x = odczytajstan(a); y = odczytajstan(a); x!= y zapiszstan(a, 200); commit;

Poziomy izolacji read uncommited oduża współbieżność, dużo problemów read commited ozabezpiecza przed dirty read o najczęściej spotykany w praktyce repeatable read Phantom read problem Tansakcja 1 Tansakcja 2 x = stansumaryczny(); y = stansumaryczny(); x!= y dodajkonto(c, 100); commit; ozabezpiecza przed unrepeatable read

Poziomy izolacji read uncommited o duża współbieżność, dużo problemów read commited ozabezpiecza przed dirty read o najczęściej spotykany w praktyce repeatable read ozabezpiecza przed unrepeatable read serializable o zabezpiecza przez phantom read

Poziomy izolacji a EJB Poziomy izolacji dotyczą poszczególnych zasobów onp. dla połączenia JDBC Connection.setIsolationLevel() ow JPA maksymalny domyślny poziom izolacji to read commited

Podejścia do współbieżności Pesymistyczne Dla JPA manager.lock(encja, LockMode.WRITE); manager.lock(encja, LockMode.READ); oba rodzaje chronią przez dirty reads i unrepeatable reads Optymistyczne ooptymistyczne blokowanie = zero blokowania konflikty ustala się na podstawie specjalnego atrybutu @Version public int version; o możliwe typy: int, Integer, short, Short, long, Long, java.sql.timestamp o sami nie dotykamy tego atrybutu o przy każdej zmianie danych w bazie atrybut jest powiększany o nie broni przed phantom read