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 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 getBookList() {
		return bookList;
	}
	public void setBookList(Set 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了,这样就可以防止一个空的身份证记录进数据库。
 

你可能感兴趣的:(Hibernate)