Dnes nebudu psát nic světoborného. Jen bych uvedl na pravou míru chybu, které jsem se dopustil v minulém článku. Není pravda, že Hibernate neumí jednosměrné one-to-many vztahy bez použití join tabulky, naopak je to docela snadné.
Na svoji obhajobu mohu uvést jen to, že jsem to v době psaní článku moc neřešil a narazil jsem na dokumentaci, která naznačovala, že to není nijak moc jednoduché. A hlavně, abych nevypadal jako úplný blbec, ponořil jsem se do specifikace EJB 3.0. Tam jsem na straně 185 našel následující text
Unidirectional one-to-many relationships may be implemented using one-to-many foreign key mappings, however, such support is not required in this release. Applications that want to use a foreign key mapping strategy for one-to-many relationships should make these relationships bidirectional to ensure portability.
Takže se mohu vymlouvat, že jsem tu relaci udělal obousměrnou, abych zařídil přenositelnost.
Ale dost už bylo výmluv, podívejme se na to jak ono mapování zařídit. Připomenu jen, že vytváříme třídu Client, která obsahuje kolekci adres a účtů (viz. obrázek)
|
@Entity @Columnprivate Long personId; @Column private String name; @OneToMany(cascade=CascadeType.ALL) @JoinColumn(name=“client_id”, nullable=false) @BatchSize(size=10) private Set<Account> accounts = new HashSet<Account>(); @OneToMany(cascade=CascadeType.ALL) @JoinColumn(name=“client_id”, nullable=false) @BatchSize(size=10) private Set<Address> addresses = new HashSet<Address>(); public void addAddress(Address address) { addresses.add(address); } //zbytek vynechán } |
Všimněte si prosím anotace @JoinColumn(name=”client_id”, nullable=false), která nám zajistí požadované mapovaní přes cizí klíč. Důležitý je druhý atribut – nullable. Ten Hibernatu říká, že cizí klíč client_id v tabulce address nesmí obsahovat null.
Oproti minulé verzi vidíme značné zjednodušení. Nemusíme se starat o plnění druhého směru relace. Dokonce ani neuděláme stejnou chybu jako já minule, když jsem zapomněl vyřešit předávání adresy mezi klienty (automatické odebrání adresy jednomu klientovi, při přidání druhému). Abych to ještě více zjednodušil, použil jsem přehlednější, i když méně výkonnou, formu inicializace množiny adres.
Takže pro shrnutí, jednosměrná one-to-many relace v Hibernate funguje, nicméně není přenositelná v rámci EJB 3.0. Ještě bych chtěl na závěr poděkovat Markovi L. za to, že mě upozornil na spoustu chyb v minulém článku a ukázal mi, že by to mapování měl Hibernate přeci jenom umět.
Zdrojové kódy můžete stáhnout zde.
Zdroje:
- JSR 220: Enterprise JavaBeansTM,Version 3.0
- Hibernate dokumentace
- EJB 3.0 – still trying to catch up to JDO and Hibernate
- Getting Started with Hibernate
Pingback: Java drobečky » Blog Archive » Nedostatky JPA
Nefunguje mi odkaz na ten priklad. Nevite jestli je chyba na moji strane?
Link opraven