hibernate一对多双向映射通常通过“多”的一端负责维护关系。但是对于list, 因为list保存关于“顺序”的信息,而多的一端没有这样的信息,所以只能由“一”的一端维护关系。
用在线图书馆举个例子。书和评论之间是一对多的关系。
book代码:
1: package org.emoticon.library.model;
2:
3: import java.util.ArrayList;
4: import java.util.Date;
5: import java.util.List;
6:
7: import javax.persistence.CascadeType;
8: import javax.persistence.Entity;
9: import javax.persistence.FetchType;
10: import javax.persistence.GeneratedValue;
11: import javax.persistence.Id;
12: import javax.persistence.JoinColumn;
13: import javax.persistence.OneToMany;
14:
15: @Entity
16: public class Book {
17:
18: private Integer id;
19: private String title;
20: private String author;
21: private String description;
22: private String publisher;
23: private int pageNumber;
24: private Date publishTime;
25: private String isbn;
26: private List<Comment> comments = new ArrayList<Comment>();
27:
28:
29: public void addComment(Comment comment){
30: comment.setBook(this);
31: comments.add(comment);
32: }
33:
34: @Id
35: @GeneratedValue
36: public Integer getId() {
37: return id;
38: }
39: public void setId(Integer id) {
40: this.id = id;
41: }
42: public String getTitle() {
43: return title;
44: }
45: public void setTitle(String title) {
46: this.title = title;
47: }
48: public String getAuthor() {
49: return author;
50: }
51: public void setAuthor(String author) {
52: this.author = author;
53: }
54: public String getDescription() {
55: return description;
56: }
57: public void setDescription(String description) {
58: this.description = description;
59: }
60: public String getPublisher() {
61: return publisher;
62: }
63: public void setPublisher(String publisher) {
64: this.publisher = publisher;
65: }
66: public int getPageNumber() {
67: return pageNumber;
68: }
69: public void setPageNumber(int pageNumber) {
70: this.pageNumber = pageNumber;
71: }
72: public Date getPublishTime() {
73: return publishTime;
74: }
75: public void setPublishTime(Date publishTime) {
76: this.publishTime = publishTime;
77: }
78: public String getIsbn() {
79: return isbn;
80: }
81: public void setIsbn(String isbn) {
82: this.isbn = isbn;
83: }
84:
85: @OneToMany(fetch = FetchType.EAGER,
86: cascade = {CascadeType.ALL})
87: @JoinColumn (name = “book_id”,
88: nullable = false)
89: @org.hibernate.annotations.IndexColumn(name = “comment_position”,
90: nullable = false,
91: base = 1)
92: public List<Comment> getComments() {
93: return comments;
94: }
95:
96: public void setComments(List<Comment> comments) {
97: this.comments = comments;
98: }
99:
100:
101: }
comment代码:
1: package org.emoticon.library.model;
2:
3: import javax.persistence.CascadeType;
4: import javax.persistence.Entity;
5: import javax.persistence.GeneratedValue;
6: import javax.persistence.Id;
7: import javax.persistence.JoinColumn;
8: import javax.persistence.ManyToOne;
9:
10: import junit.framework.Assert;
11:
12: @Entity
13: public class Comment {
14: private Integer id;
15: private int rate;
16: private String title;
17: private String content;
18: private Book book;
19:
20: @Id
21: @GeneratedValue
22: public Integer getId() {
23: return id;
24: }
25: public void setId(Integer id) {
26: this.id = id;
27: }
28: public int getRate() {
29: return rate;
30: }
31:
32: public void setRate(int rate) {
33: Assert.assertTrue(rate > 0 && rate < 6);
34: this.rate = rate;
35: }
36:
37: public String getTitle() {
38: return title;
39: }
40:
41: public void setTitle(String title) {
42: this.title = title;
43: }
44:
45: public String getContent() {
46: return content;
47: }
48: public void setContent(String content) {
49: this.content = content;
50: }
51:
52: @ManyToOne(cascade = {CascadeType.ALL})
53: @JoinColumn(name=”book_id”,
54: nullable = false,
55: updatable = false,
56: insertable = false)
57: public Book getBook() {
58: return book;
59: }
60:
61: public void setBook(Book book) {
62: this.book = book;
63: }
64:
65: }
测试代码:
1: package org.emoticon.library.manager;
2:
3: import org.emoticon.core.test.DaoTestCase;
4: import org.emoticon.library.model.Book;
5: import org.emoticon.library.model.Comment;
6:
7: public class BookManagerTest extends DaoTestCase {
8: private BookManager manager;
9:
10: private static final String commentTitle = “a good book”;
11:
12: public void setManager(BookManager manager) {
13: this.manager = manager;
14: }
15:
16: public void testSave(){
17: Book entity = new Book();
18: entity.setTitle(“thinking in java”);
19: entity.setDescription(“for newbie”);
20:
21: Comment comment = new Comment();
22: comment.setTitle(commentTitle);
23: comment.setContent(“I like it.”);
24: comment.setRate(5);
25:
26: Comment comment2 = new Comment();
27: comment2.setTitle(commentTitle + “2″);
28: comment2.setContent(“I like it2.”);
29: comment2.setRate(4);
30:
31: entity.addComment(comment);
32: entity.addComment(comment2);
33:
34: manager.save(entity);
35: assertNotNull(entity.getId());
36: entity = manager.get(entity.getId());
37: //assertEquals(entity.getComments().get(0).getTitle(), commentTitle);
38: assertNotNull(entity);
39: this.setComplete();
40: }
41: }
这里需要注意:很多时候你在一对多list关联的时候,不真的需要indexcolumn来维护顺序。比如在线图书馆,如果没有indexcolumn也没问题。因为comment总是一条一条加的,那么indexcolumn那一列其实总不变。只有一下添加多个comment的时候,如上面代码,indexcolumn才会增加。comment的id本身就可以用来排序。
在线图书馆其实用不上indexcolumn, 实现的时候想错了,既然已经调通了,就记下来以后也许用得上。