MappedBy attribute value in annotation?

I am new to sleep mode. I tried to create a one-to-one mapping between the Person object and PersonDetail in the following code:

@Entity public class Person { private int personId; private String personName; private PersonDetail personDetail; @OneToOne(mappedBy="person") public PersonDetail getPersonDetail() { return personDetail; } public void setPersonDetail(PersonDetail personDetail) { this.personDetail = personDetail; } @Id @GeneratedValue public int getPersonId() { return personId; } public void setPersonId(int personId) { this.personId = personId; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } } @Entity public class PersonDetail { private int personDetailId; private String zipCode; private String job; private double income; private Person person; @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER) public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Id @GeneratedValue public int getPersonDetailId() { return personDetailId; } public void setPersonDetailId(int personDetailId) { this.personDetailId = personDetailId; } public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public double getIncome() { return income; } public void setIncome(double income) { this.income = income; } } 

I want PersonDetail to be the owner of the object (I know the opposite is correct, but I just want to check). What I don't understand is the use of the mappedBy attribute that I entered in the Person object. If I delete it, I get the following error: "Could not determine type for: com.hibernate.onetoonemapping.PersonDetail, in table: Person, for columns: [org.hibernate.mapping.Column (personDetail)]"

What does this mappedBy attribute do? I read that the mappedBy attribute is placed on the side not owned by the owner. But what is he doing?

+6
source share
3 answers

This means that this relationship between entites has already been mapped, so you do not do this twice. You just say "Hey, it's done there" using the mappedBy attribute.

+7
source

If you want to make the relationship bidirectional (accessible from either side of the entity), you used mappedBy on the side not associated with the owner, because you can only define the relationship once.

mappedBy tells Hibernate how to instantiate your objects and load data into them. It should refer to the name of the field in the class you are annotating, PersonDetail in this case, where the relation is defined.

+4
source

In your scenario, the mappedBy attribute should not have any effect.

I was confused by the name of the primary key (it differs from "id"), but using a non-standard name as an identifier (somehow, as expected) does not cause the problem that you are encountering.

I experimented with the mappedBy parameter in the context of the OneToMany and OneToOne associations and would like to share my findings. I have a similar scenario for testing purposes and to illustrate the impact.

Person.class:

 @Entity public class Person { @Id @GeneratedValue private Long id; @Column(name = "name") private String name; @OneToOne private Address address; } 

Address.class (for OneToOne tests):

 @Entity public class Address { @Id @GeneratedValue private Long id; @Column(name = "address") private String address; @OneToOne(mappedBy="address") private Person person; @OneToMany(cascade = CascadeType.ALL) private Set<Phone> phone = new HashSet<Phone>(); } 

Phone.class (for OneToMany tests):

 @Entity public class Phone { @Id @GeneratedValue private Long id; @ManyToOne(optional = false) private Person person; @Column(name = "number") private String number; } 

By moving the "mappedBy" parameter for the OneToOne association, in any case, the sql statements executed by hibernation remain the same:

 Hibernate: /* insert domain.Address */ insert into Address (id, address) values (default, ?) Hibernate: /* insert domain.Person */ insert into Person (id, address_id, name) values (default, ?, ?) 

For OneToMany associations , I found that if you do not specify "mappedBy", hibernate automatically uses the join table, while with the parameter "mappedBy" the association is displayed as a separate column in the entity table.

If I use ...

  @OneToMany(cascade = CascadeType.ALL) private Set<Phone> phone = new HashSet<Phone>(); 

... Transferring a person with one phone entry leads to the following operations that must be performed:

 Hibernate: /* insert domain.Phone */ insert into Phone (id, number, person_id) values (default, ?, ?) Hibernate: /* insert collection row domain.Person.phone */ insert into Person_Phone (Person_id, phone_id) values (?, ?) 

While using ...

  @OneToMany(mappedBy="id", cascade = CascadeType.ALL) private Set<Phone> phone = new HashSet<Phone>(); 

leads to a slightly different relational model, which is closer to what might be expected in this case:

 Hibernate: /* insert domain.Phone */ insert into Phone (id, number, person_id) values (default, ?, ?) 
+3
source

Source: https://habr.com/ru/post/906592/


All Articles