One-to-One mappedBy的影響
Hibernate Annotations的說明
The association may be bidirectional. In a bidirectional relationship, one of the sides (and only one) has to be
the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible
for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on
the owner side.
在Hibernate中雙向的Relationship的維護上,必定有一方為Owner來記錄此Relationship.
而mappedBy就是為了宣告其本身不負責記錄Relationship,交由另一方記錄所使用的annotation attribute.
Bidirectional 的 One-to-One通常還是有主從的概念,以下列Person為主,Passport為從來看
(1)將mappedBy設在Person(從)上
public class Person implements Serializable {
@Id
@GeneratedValue(generator = "uuid-gen")
@GenericGenerator(name = "uuid-gen", strategy = "uuid")
@Column(length = 32)
private String id;
@OneToOne(cascade= CascadeType.ALL)
private Passport passport;
}
public class Passport implements Serializable {
@Id
@GeneratedValue(generator = "uuid-gen")
@GenericGenerator(name = "uuid-gen", strategy = "uuid")
@Column(length = 32)
private String identificationCode;
@OneToOne(mappedBy="passport")
private Person owner;
}
Create Table SQL
create table Passport (identificationCode varchar(32) not null, primary key (identificationCode))
create table Person (id varchar(32) not null, version integer, name varchar(50), firstName varchar(50), lastName varchar(50), mutable bit, birthday date, age integer, modifyDate timestamp, description longvarchar, passport_identificationCode varchar(32), primary key (id))
alter table Person add constraint FK8E488775EB061869 foreign key (passport_identificationCode) references Passport
Hibernate SQL Execution
Hibernate: insert into Person (version, name, firstName, lastName, mutable, birthday, age, modifyDate, description, passport_identificationCode, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select this_.id as id0_1_, this_.version as version0_1_, this_.name as name0_1_, this_.firstName as firstName0_1_, this_.lastName as lastName0_1_, this_.mutable as mutable0_1_, this_.birthday as birthday0_1_, this_.age as age0_1_, this_.modifyDate as modifyDate0_1_, this_.description as descrip10_0_1_, this_.passport_identificationCode as passport11_0_1_, passport2_.identificationCode as identifi1_1_0_ from Person this_ left outer join Passport passport2_ on this_.passport_identificationCode=passport2_.identificationCode
Hibernate: insert into Passport (identificationCode) values (?)
Hibernate: update Person set version=?, name=?, firstName=?, lastName=?, mutable=?, birthday=?, age=?, modifyDate=?, description=?, passport_identificationCode=? where id=? and version=?
Hibernate會將passport_identificationCode建在Person的Table中,而在Select時,會一併帶出Passport的資料
(2)將mappedBy設在Passport(主)上
public class Person implements Serializable {
@Id
@GeneratedValue(generator = "uuid-gen")
@GenericGenerator(name = "uuid-gen", strategy = "uuid")
@Column(length = 32)
private String id;
@OneToOne(mappedBy="owner",cascade= CascadeType.ALL)
private Passport passport;
}
public class Passport implements Serializable {
@Id
@GeneratedValue(generator = "uuid-gen")
@GenericGenerator(name = "uuid-gen", strategy = "uuid")
@Column(length = 32)
private String identificationCode;
@OneToOne
private Person owner;
}
Create Table SQL
create table Passport (identificationCode varchar(32) not null, owner_id varchar(32), primary key (identificationCode))
create table Person (id varchar(32) not null, version integer, name varchar(50), firstName varchar(50), lastName varchar(50), mutable bit, birthday date, age integer, modifyDate timestamp, description longvarchar, primary key (id))
alter table Passport add constraint FK4C60F032538A0EEB foreign key (owner_id) references Person
Hibernate SQL Execution
Hibernate: insert into Person (version, name, firstName, lastName, mutable, birthday, age, modifyDate, description, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select this_.id as id0_1_, this_.version as version0_1_, this_.name as name0_1_, this_.firstName as firstName0_1_, this_.lastName as lastName0_1_, this_.mutable as mutable0_1_, this_.birthday as birthday0_1_, this_.age as age0_1_, this_.modifyDate as modifyDate0_1_, this_.description as descrip10_0_1_, passport2_.identificationCode as identifi1_1_0_, passport2_.owner_id as owner2_1_0_ from Person this_ left outer join Passport passport2_ on this_.id=passport2_.owner_id
Hibernate: insert into Passport (owner_id, identificationCode) values (?, ?)
Hibernate: update Person set version=?, name=?, firstName=?, lastName=?, mutable=?, birthday=?, age=?, modifyDate=?, description=? where id=? and version=?
Hibernate會將owner_id建在Passport的Table中,而在Select時,不會一併帶出Passport的資料
可能的話,應該還是將mappedBy設在(主)的那一方上,讓(從)的一方記錄relationship的欄位.
否則的話就如同Component,不如就整在同一Table裡,還可以省去join的時間.