Hibernate One to Many Tutorial za bilješke

1. Uvod

Ovaj brzi vodič za hibernaciju provest će nas kroz primjer a jedan-prema-mnogima mapiranje pomoću JPA bilješki, alternative XML-u.

Također ćemo naučiti što su dvosmjerni odnosi, kako mogu stvoriti nedosljednosti i kako ideja vlasništva može pomoći.

2. Opis

Jednostavno rečeno,jedan prema mnogima preslikavanje znači da se jedan redak u tablici preslikava na više redaka u drugoj tablici.

Pogledajmo sljedeći dijagram odnosa entiteta da bismo vidjeli a jedan prema mnogima udruga:

U ovom ćemo primjeru implementirati sustav kolica u kojem imamo tablicu za svaku košaricu i drugu tablicu za svaku stavku. Jedna košarica može imati mnogo predmeta, pa ovdje imamo jedan-prema-mnogima mapiranje.

Način na koji ovo funkcionira na razini baze podataka je da imamo cart_id kao primarni ključ u kolica stol i također a cart_id kao strani ključ u predmeta.

Način na koji to radimo u kodu je s @OneToMany.

Mapirajmo Košarica razred do Predmeti objekt na način koji odražava odnos u bazi podataka:

košarica javne klase {// ... @OneToMany (mappedBy = "cart") private Set items; // ...}

Možemo dodati i referencu na Košarica u Predmeti koristeći @ManyToOne, čineći ovo dvosmjernim odnosom. Dvosmjerno znači da u mogućnosti smo pristupiti predmeta iz kolica, I također kolica iz predmeta.

The mapiranBy svojstvo je ono što koristimo kako bismo Hibernateu rekli koju varijablu koristimo za predstavljanje roditeljske klase u našoj podređenoj klasi.

Sljedeće tehnologije i knjižnice koriste se za razvoj uzorka Hibernate aplikacije koja se implementira jedan-prema-mnogima udruga:

  • JDK 1.8 ili noviji
  • Hibernate 5
  • Maven 3 ili noviji
  • H2 baza podataka

3. Postavljanje

3.1. Postavljanje baze podataka

Ispod je naša skripta baze podataka za Košarica i Predmeti stolovi. Ograničenje stranog ključa koristimo za jedan prema mnogima mapiranje:

STVORI TABLICU `Cart` (` cart_id` int (11) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`cart_id`)) MOTOR = InnoDB AUTO_INCREMENT = 5 ZADATAK KARSETET = utf8; STVORI TABELU `Predmeti` (` id` int (11) unsigned NOT NULL AUTO_INCREMENT, `cart_id` int (11) unsigned NOT NULL, PRIMARY KEY (` id`), KEY `cart_id` (` cart_id`), CONSTRAINT `items_ibfk_1 `STRANI KLJUČ (` cart_id`) LITERATURA `Košarica` (` cart_id`)) MOTOR = InnoDB AUTO_INCREMENT = 7 ZADATAK KARSETET = utf8;

Postavljanje baze podataka je spremno, pa prijeđimo na stvaranje primjera hibernacije.

3.2. Ovisnosti Mavena

Zatim ćemo našoj ovisnosti dodati Hibernate i H2 driver pom.xml datoteka. Ovisnost o hibernaciji koristi zapise JBoss i automatski se dodaje kao prijelazne ovisnosti:

  • Hibernate verzija 5.2.7.Finalni
  • Verzija H2 upravljačkog programa 1.4.197

Posjetite središnje spremište Maven za najnovije verzije hibernacije i ovisnosti o H2.

3.3. Konfiguracija hibernacije

Evo konfiguracije hibernacije:

  org.h2.Driver jdbc: h2: mem: spring_hibernate_one_to_many sa org.hibernate.dialect.H2Dialect thread true 

3.4. HibernateAnnotationUtil Razred

Uz HibernateAnnotationUtil klase, samo trebamo uputiti novu konfiguracijsku datoteku hibernacije:

privatna statička SessionFactory sessionFactory; private SessionFactory buildSessionFactory () {ServiceRegistry serviceRegistry = novi StandardServiceRegistryBuilder (). configure ("hibernate-annotation.cfg.xml"). build (); Metapodaci metapodaci = novi MetadataSources (serviceRegistry) .getMetadataBuilder (). Build (); SessionFactory sessionFactory = metadata.getSessionFactoryBuilder (). Build (); return sessionFactory; } javna SessionFactory getSessionFactory () {if (sessionFactory == null) sessionFactory = buildSessionFactory (); return sessionFactory; }

4. Modeli

Konfiguracije povezane s mapiranjem izvest će se pomoću JPA bilješki u klasama modela:

@Entity @Table (name = "CART") javna klasa Košarica {// ... @OneToMany (mappedBy = "cart") private Set items; // geteri i postavljači}

Imajte na umu da @OneToMany napomena se koristi za definiranje svojstva u Predmeti klasa koja će se koristiti za mapiranje mapiranBy varijabilna. Zbog toga imamo svojstvo pod nazivom „kolica”U Predmeti razred:

@Entity @Table (name = "ITEMS") stavke javne klase {// ... @ManyToOne @JoinColumn (name = "cart_id", nullable = false) košarica privatne košarice; javne stavke () {} // getters and setters} 

Također je važno napomenuti da @ManyToOne bilješka je povezana s Košarica varijabla klase. @JoinColumn napomena upućuje na mapirani stupac.

5. Na djelu

U testnom programu stvaramo razred s a glavni() metoda za dobivanje Hibernate Session i spremanje objekata modela u bazu podataka koja implementira jedan-prema-mnogima udruga:

sessionFactory = HibernateAnnotationUtil.getSessionFactory (); session = sessionFactory.getCurrentSession (); System.out.println ("Sesija stvorena"); tx = session.beginTransaction (); session.save (kolica); session.save (stavka1); session.save (stavka2); tx.commit (); System.out.println ("Cartitem1, inozemni ključ Cartitem2, inozemni ključ Cartmany-to-one">6. The @ManyToOne Bilješka

Kao što smo vidjeli u odjeljku 2, možemo odrediti a mnogo-prema-jednom odnos pomoću @ManyToOne bilješka. A mnogo-prema-jednom mapiranje znači da su mnogi primjerci ovog entiteta mapirani u jedan primjerak drugog entiteta - mnogo predmeta u jednoj košarici.

The @ManyToOne anotacija nam omogućuje i stvaranje dvosmjernih odnosa. To ćemo detaljno pokriti u sljedećih nekoliko pododjeljaka.

6.1. Nedosljednosti i vlasništvo

Sad, ako Košarica referencirano Predmeti, ali Predmeti nije zauzvrat uputio Košarica, naš bi odnos bio jednosmjeran. Predmeti bi također imali prirodnu konzistenciju.

U našem slučaju, međutim, odnos je dvosmjeran, donoseći mogućnost nedosljednosti.

Zamislimo situaciju u kojoj programer želi dodati stavka1 do kolica i stavka2 do kolica2, ali griješi tako da reference između kolica2 i stavka2 postati nedosljedan:

Košarica1 = nova Košarica (); Košarica2 = nova Košarica (); Predmeti item1 = novi Predmeti (cart1); Artikli item2 = novi Artikli (košarica2); Postavi itemsSet = novi HashSet (); itemsSet.add (item1); itemsSet.add (item2); cart1.setItems (itemsSet); // pogrešno!

Kao što je prikazano gore, stavka2 reference kolica2, dok kolica2 ne upućuje stavka 2, a to je loše.

Kako Hibernate treba spasiti stavka2 u bazu podataka? Htjeti stavka2 referenca stranog ključa kolica1 ili kolica2?

Tu dvosmislenost rješavamo koristeći ideju vlasničke strane odnosa; reference koje pripadaju strani vlasnika imaju prednost i spremaju se u bazu podataka.

6.2. Predmeti kao Vlasnička strana

Kao što je navedeno u specifikaciji JPA u odjeljku 2.9, dobra je praksa za označavanje mnogo-prema-jednom strana kao strana posjedovanja.

Drugim riječima, Jatems bila bi vlasnička strana i Košarica inverzna strana, što smo upravo učinili ranije.

Pa kako smo to postigli?

Uključivanjem mapiranBy atribut u Košarica razreda, označavamo ga kao obrnutu stranu.

Istodobno također bilježimo Predmeti.kolica polje sa @ManyToOne, izrada Predmeti strana koja posjeduje.

Vraćajući se našem primjeru "nedosljednosti", Hibernate sada zna da stavka2Referenca je važnija i spasit će stavka2Referenca na bazu podataka.

Provjerimo rezultat:

item1 ID = 1, ID košarice s inozemnim ključem = 1 item2 ID = 2, ID košarice s inozemnim ključem = 2

Iako kolica reference stavka2 u našem isječku, stavka2Referenca na kolica2 se sprema u bazu podataka.

6.3. Košarica kao Vlasnička strana

Također je moguće označiti jedan-prema-mnogima strana kao strana koja posjeduje, i mnogo-prema-jednom strana kao inverzna strana.

Iako ovo nije preporučena praksa, krenimo i pokušajmo.

Isječak koda u nastavku prikazuje implementaciju jedan prema mnogima strana kao strana posjedovanja:

predmeti javne klaseOIO {// ... @ManyToOne @JoinColumn (name = "cart_id", insertable = false, Updatable = false) privatna košarica CartOIO; // ..} javna klasa CartOIO {// .. @OneToMany @JoinColumn (name = "cart_id") // moramo duplicirati fizičke podatke private Set stavke; // ..} 

Primijetite kako smo uklonili mapiranBy element i postavite mnogo-prema-jednom @JoinColumn kao umetnuti i moguće ažurirati do lažno.

Ako pokrenemo isti kod, rezultat će biti suprotan:

item1 ID = 1, ID košarice s inozemnim ključem = 1 item2 ID = 2, ID košarice s inozemnim ključem = 1

Kao što je gore prikazano, sada stavka2 pripada kolica.

7. Zaključak

Vidjeli smo kako je lako implementirati jedan prema mnogima odnos s Hibernate ORM i H2 bazom podataka koristeći JPA bilješke.

Pored toga, naučili smo o dvosmjernim odnosima i kako primijeniti pojam posjedovanja strane.

Izvorni kod u ovom članku možete pronaći na GitHubu.