JPA - the relationship one-to-many and many-to-one In this article I would like to present the mapping of a one-to-many and the twin her a many-to-one. In this type of relationship we can distinguish between the entities being a parent - on one side of the relationship and any number of sub-entities - the other side of the relationship.
This relationship is so special that, in the relational world of its implementation is the starting point to implement a one-to-one and many-to-many.
distinguish between the following options for the relationship of this type:
- two-way relationship jeden-do-wielu/wiele-do-jednego: the parent has a collection of references to child objects that have reference to the parent;
- unidirectional one-to-many: the parent has a collection of references to child objects;
- one-way many-to-one: a child has a reference to the parent;
first Example - an area traditionally
problem for the auxiliary will use very complex example. And here's the object model:
is a system of two classes Person
and
Contact
. The latter represents the contact details such as phone number or email address.
An
aggregates completely
Kontatk
's (bond-type composition), which also has reflected the supremacy of one being to another. Of course, the relationship in question also concerns the type of bond association and normal aggregation, but chose the theme because the relational model, this will involve an additional reduction
not null. In the relational world
exemplary model will be the following:
second Two-way relationship wiele-do-jednego/jeden-do-wielu
The object model in which there are connections between objects, very often we expect the possibility of two-way "navigation" between related objects. In our example, this means that we expect to upgrade the facility
Person
to its related objects
Contact
and vice versa.
To meet these requirements we must appropriately map these two classes.
2.1. Mapping class Contact
Entity
Contact the owner of a link, because it has a foreign key to entity
person.
@ Entity @ Table (name = "contact") public class Contact {... private Person person; @ ManyToOne (optional = false) @ JoinColumn (name = "oso_id") / / default column to be called osoba_oso_id getOsoba public Person () {return person;}}
JPA requires only that a child in the facility to mark a reference to the parent with the annotation @ ManyToOne
. But I also overwrite some default setting. And so:
- set the attribute
optional = false
this annotation, which means that the reference to
person must be set, which will be expressed during the automatic generation of database schema by adding NOT NULL constraints;
; - Through the @ JoinColumn annotation
set the column name, which is a foreign key to table Person
. By default, that was used in a column named [nazwa_tabeli_nadrzędnej] _ [nazwa_klucza_głównego_tabeli_nadrzędnej]
2.2. Mapping the Person class
@ Entity @ Table (name = "person") public class Person {... private List contacts \u0026lt;Contact>; @ OneToMany (cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy = "person") @ Cascade ({org.hibernate.annotations.CascadeType.DELETE_ORPHAN}) public List \u0026lt;Contact> getKontakty ( ) {return contacts;} public void dodajKontakt (Contact contact) {if (null == contact) {contacts = new ArrayList \u0026lt;Contact> ();} kontakt.setOsoba (this); kontakty.add (contact);}}
For the parent is required to determine the reference collections of child objects with entries
@ OneToMany
. Because this is a two-way binding, and mapping to the relational model has already been defined in the class
Contact
, it should express this by attribute
mappedBy
this annotation, which should be assigned a value that is the name of references (in the sub-object) to obietku parent. The attribute
mappedBy
be used not only to avoid having a double set of physical parameters of the relational model, but mainly because, to avoid duplicate records in the database. Attribute
mappedBy
is unavailable for the annotation @ ManyToOne
.
Besides mapping is equipped with the parameters defining the cascade action, but they write some more in the discussion of preservation and disposal facilities.
2.3. Consolidation of objects in the database objects can
Fixation be implemented in a separable or cascading. Scheme of distributive
fixation of objects in our example would be as follows. First, create and save object
Person: Person
o = new Person (); em.persist (o);
Then, create, relationship with the person and write the object
Contact: Contact
k = new Contact ("tel "," +48123124234 "); o.dodajKontakt (k); em.persist (k);
Here I will note that the method
dodajKontakt
adds a contact to the collection
contacts in the building of
and sets the reference
person in the building
k
.
If you want to fix the object
Contact
in the next transaction, then he must set the appropriate references to the object
person. Assuming that we have only the id of the person that can do the following: Contact
k = new Contact ("GG", "124234") = Person with em.getReference (Osoba.class, osobaId); k.setOsoba ( o); em.persist (k);
I'd be manually create an instance
person and setting the id field
not work.
fixation cascade of objects. Often the need for fixation of the whole tree of objects, such as a parent - the root of the tree (
person) and the related child objects (
Contact
). JPA allows you to do this by performing operations on the parent object fixation. At the same time, be sure to set the cascade attribute
the
CascadeType.PERSIST
in mapping - as was done in the mapping class
person for property
contacts.
cascading effect fusing of objects can also be set on the side of the child, but it appears to be very practical.
2.4. Removing objects from DB
As well as consolidating and removing objects can be separated or cascaded.
Cascading delete objects is analogous to the cascade fixation. Ie. performing surgery to remove the main object - the root of the tree of objects, are automatically removed the related child objects. Here you should be sure to set the cascade attribute
the
CascadeType.REMOVE
in mapping - as was done in the mapping class
person for property
contacts. Implementation of the JPA should be removed before removing the child objects parent, to avoid infringement of database constraints. However, the removal of these may not be optimal. For example hibernate'owa implementation removes each object separately after its id, while a better solution would be to remove all objects from one group one question referring to the foreign key to being the parent. Activities
cascade delete objects can not be set on the side of the child.
Following the removal of the child objects in the relationship can be used to extend jeden-do-wielu/wiele-do-jednego hibernate'owe - Cascading effects
delete-orphan. However, when in the mapping of a parent class, a collection of references to child objects denote endorsement
@ Cascade ({org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
, after removing an object from the collection and consolidation of the parent object, removed object from the collection will also be removed from the database.
o.getKontakty (). Remove (k); em.persist (o);
When using this extension should be remembered that for the parent at least once settled, can not be around with the collection of child objects, say a new instance of ArrayList
, and the attempt to consolidate such a facility simply fails. This is because hibernate uses its own implementations of the collection -
persistence
collections, which help in the implementation of the delete-orphan.
Removing separable. No, no problem to delete the child objects in a manner separable. Moreover, without the use of a series of extensions hibernate'owego delete-orphan, is the only way to get rid of the database in a single child object.
But to dispense with a series of disposal for the parent objects is not very attractive. If the database is assumed restriction that the foreign key to the parent entity can not be empty, such an operation at all will fail. Generally what happens to this further depends on the settings of cascading on the database.
third One-way many-to-one
compared to two-way relationship wiele-do-jednego/jeden-do-wielu, class
Contact
and its mapping remains unchanged, but with class
person will be removed the link to the class
Contact
. This approach prevents
of cascading configuration (other than those specified in the schema of the database) wyzwalanymi by operations on the object
person. Alternatively, you can specify action cascade triggered by operations on the object
Contact
.
In this example, I have a lot of one-way-to-one does not make much practical use.
4th Unidirectional one-to-many
compared to two-way relationship wiele-do-jednego/jeden-do-wielu, the class will disappear
Contact link to the class
person, while the class Person
and mapping changes as follows : @ Entity
@ Table (name = "person") public class Person {... private List contacts \u0026lt;Contact>; @ OneToMany (cascade = {CascadeType.PERSIST, CascadeType.REMOVE}) @ Cascade ({org.hibernate.annotations.CascadeType.DELETE_ORPHAN}) @ JoinColumn (name = "oso_id" Nullable = false) public List \u0026lt;Contact> getKontakty () {return contacts;} public void dodajKontakt (Contact contact) {if (null == contact) {contacts = new ArrayList \u0026lt;Contact> ();} kontakty.add (contact);}}
As you can see has changed the method
dodajKontakt
, which no longer contains the user object binding
contact with the object
Person
. But most importantly, changed a little bit mapping. Since the class
Contact
does not contain been mapping this relationship is:
- disappeared attribute definition
mappedBy
the annotation @ OneToMany
;
- to map the property
contacts
been added
@ JoinColumn annotation
, which like the Contact
class is used to specify the column in the entity
Contact
, which is a foreign key to the Person entity
. Otherwise, by default, the table would be used an intermediary, like a many-to-many, called
[nazwa_tabeli_nadrzędnej] _ [nazwa_tabeli_podrzędnej]
which would include two foreign keys to the tables with the following schema names
[tablename] _ [nazwa_klucza_głównego]
.
For example, I have presented the use of a unidirectional one-to-many is quite a reasonable approach. The only thing that is lost is the ability to write objects
Contact
whatever object
person. Has also lost the ability to define a cascading action from the object
Contact
, but to take advantage of this possibility in this case, and so there is a reasonable condition.
5th Support Resources
Example Source Files
JPA - first steps Hibernate Annotations - 2.2.5. Mapping entity bean Associations / relationships 2.4. Hibernate Annotation Extensions JPA specification