天天看點

hibernate 注解方式 屬性mappedBy詳解

遇到的問題:

在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了,這樣就可以防止一個空的身份證記錄進資料庫。

繼續閱讀