遇到的問題:
在hibernate一對多的注解中,由于沒有添加mappedBy=“多端的關聯屬性名”,導緻在更新資料時,外鍵被置空(null),意思是由多的一端來維護關系。(一般由有外鍵的一方來維護)
解決方法:
一:Author(作者) 多:Book(書籍)
其代碼分别如下: Author的pojo代碼:
package com.jason.domain;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@Entity
@Table(name = "Author")
public class Author implements Serializable{
private Integer id;
private String authorName;
private Set<Book> bookList;
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="generator")
@SequenceGenerator(sequenceName="Author_SEQ",
name="generator",initialValue=1,allocationSize=1)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "authorName", length = 30)
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
@OneToMany(mappedBy="author") //添加mappedBy="author"解決,但注意不能與@JoinColumn(name="author_id")共存
@Cascade(value= {CascadeType.ALL}) //設定級聯關系
public Set<Book> getBookList() {
return bookList;
}
public void setBookList(Set<Book> bookList) {
this.bookList = bookList;
}
@Override
public String toString() {
return "Author [id=" + id + ", authorName=" + authorName + "]";
}
}
Book的pojo代碼:
package com.jason.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@Entity
@Table(name = "Book")
public class Book implements Serializable{
private Integer id;
private String bookName;
private Float price;
private Author author;
public Book() {
}
public Book(String bookName, Float price) {
this.bookName = bookName;
this.price = price;
}
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="generator")
@SequenceGenerator(sequenceName="Book_SEQ",
name="generator",initialValue=1,allocationSize=1)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "bookName", length = 30)
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
//scale:小數位數
@Column(name = "price",scale = 1)
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
@ManyToOne
@JoinColumn(name="author_id")
@Cascade(CascadeType.ALL)
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
@Override
public String toString() {
return "Book [id=" + id + ", bookName=" + bookName + ", price=" + price + ", author=" + author + "]";
}
}
詳細知識:
mappedBy:
1、隻有@OneToOne,@OneToMany,@ManyToMany上才有mappedBy屬性,ManyToOne不存在該屬性;
2、mappedBy标簽一定是定義在被擁有方的(被控方),他指向擁有方;
3、mappedBy的含義,應該了解為,擁有方能夠自動維護跟被擁有方的關系,當然,如果從被擁有方,通過手工強行來維護擁有方的關系也是可以做到的;
4、mappedBy跟joinColumn/JoinTable總是處于互斥的一方,可以了解為正是由于擁有方的關聯被擁有方的字段存在,擁有方才擁有了被擁有方。mappedBy這方定義JoinColumn/JoinTable總是失效的,不會建立對應的字段或者表。
下面是一個例子:
人跟身份證雙向關聯
在person裡面定義的注釋代碼:
@OneToOne(cascade = CascadeTye.ALL,optional = true)
public IDCard getIdCard(){
return idCard;
}
在idcard裡面定義的注釋代碼:
@OneToOne(cascade = CascadeType.ALL,mappedBy = "idCard",optional = false)
public Person getPerson(){
return person;
}
解釋: 多了一個mappedBy這個方法,他表示什麼呢?它表示目前所在表和Person的關系是定義在Person裡面的idCard這個成員上面的,他表示此表是一對一關系中的從表,也就是關系是在person表中維護的,這是最重要的。Person表是關系的維護者,有主導權,它有個外鍵指向IDCard。
我們也可以讓主導權在IDCard上面,也就是讓他産生一個指向Person的外鍵,這也是可以的,但是最好讓Person來維護整個關系,這樣更符合我們的思維。
我們也可以看到在Person裡面的IDCard是注釋optional=true,也就是說一個人是可以沒有身份證的,但是一個身份證是不可以沒有人的,是以在IDCard裡面注釋Person的時候,optional=false了,這樣就可以防止一個空的身份證記錄進資料庫。