2012-01-22 33 views
6

Tôi là người mới ngủ đông. Tôi đã cố gắng để tạo ra một ánh xạ một-một giữa Người và PersonDetail thực thể trong đoạn mã sau:Ý nghĩa thuộc tính mappedBy trong chú thích?

@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; 
    } 

} 

Tôi muốn điều đó PersonDetail nên là đối tượng sở hữu (Tôi biết rằng ngược lại là đúng, nhưng tôi chỉ muốn kiểm tra). Những gì tôi không hiểu là việc sử dụng thuộc tính mappedBy mà tôi đã đưa vào thực thể Person. Nếu tôi xóa nó, tôi nhận được lỗi sau: "Không thể xác định loại cho: com.hibernate.onetoonemapping.PersonDetail, tại bảng: Người, cho cột: [org.hibernate.mapping.Column (personDetail)]"

Thuộc tính mappedBy này làm gì? Tôi đã đọc thuộc tính mappedBy được đặt ở bên không sở hữu. Nhưng chính xác thì nó làm gì?

Trả lời

7

Điều đó có nghĩa là mối quan hệ giữa các đơn vị đã được lập bản đồ, do đó bạn không làm điều đó hai lần. Bạn chỉ cần nói "Hey nó được thực hiện trên đó" bằng cách sử dụng thuộc tính mappedBy.

3

Trong trường hợp của bạn, thuộc tính mappedBy sẽ không có bất kỳ tác động nào.

Tôi đã nhầm lẫn về tên của khóa chính (khác với "id"), nhưng sử dụng tên không chuẩn làm số nhận dạng (bằng cách nào đó như mong đợi) không gây ra sự cố bạn đang gặp phải.

Tôi đã thử nghiệm với thông số mappedBy trong ngữ cảnh của các hiệp hội OneToMany và OneToOne và muốn chia sẻ các phát hiện của tôi. Tôi có một kịch bản tương tự cho mục đích thử nghiệm và để minh họa cho tác động.

Person.class:

@Entity 
public class Person { 

    @Id 
    @GeneratedValue 
    private Long id; 

    @Column(name = "name") 
    private String name; 

    @OneToOne 
    private Address address; 
} 

Address.class (ví OneToOne kiểm tra):

@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 (ví OneToMany kiểm tra):

@Entity 
public class Phone { 

    @Id 
    @GeneratedValue 
    private Long id; 

    @ManyToOne(optional = false) 
    private Person person; 

    @Column(name = "number") 
    private String number; 
} 

Bằng cách di chuyển xung quanh "mapp edBy" tham số cho hiệp hội OneToOne, trong mọi trường hợp báo cáo sql thực hiện bởi Hibernate vẫn giữ nguyên:

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

Đối OneToMany hiệp hội tôi thấy rằng nếu bạn không xác định 'mappedBy' ngủ đông tự động sử dụng một bảng tham gia , trong khi với tham số "mappedBy", liên kết được ánh xạ dưới dạng một cột riêng biệt trong bảng thực thể.

Nếu tôi sử dụng ...

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

... persising một người có kết quả vào một điện thoại trong các câu sau đây được thực hiện:

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 
     (?, ?) 

Trong khi sử dụng ...

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

kết quả trong một mô hình quan hệ hơi khác nhau đó là gần gũi hơn với những gì người ta sẽ có thể mong đợi trong trường hợp này:

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

Khi bạn muốn thực hiện một mối quan hệ hai chiều (truy cập từ hai bên thực thể) bạn đã sử dụng mappedBy ở bên không sở hữu vì bạn chỉ có thể xác định mối quan hệ một lần.

mappedBy thông báo cho Hibernate cách tạo các cá thể của các thực thể của bạn và tải dữ liệu vào chúng. Nó nên tham chiếu đến tên trường trong lớp mà bạn đang chú thích, PersonDetail trong trường hợp này, trong đó mối quan hệ được xác định.

Các vấn đề liên quan