hibernate annotation List映射双向一对多实体关系



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, 实现的时候想错了,既然已经调通了,就记下来以后也许用得上。