2011-03-22 48 views

回答

1

我建议开始有三个Entities,一个正在被标记的对象(在SO例子的情况下,这将是一个Post),一个牵着你的标签定义(你可以调用这个Tag ),以及两者之间的映射(称为这一个TaggedPost)。

然后分配的基本过程TagPost云一样的东西:

  1. 看看是否与给定名称的Tag已经存在,如果是,利用现有的一个,否则插入一个新的。
  2. 创建一个新的TaggedPost实例从步骤1

链接PostTag要从Post你只是删除相应的TaggedPost实体删除Tag

您可以使用Hibernate注释将适用于给定Post的标记集作为Java集合公开,以便您可以仅说getTags()即可获取所有标记。并且您可以在Tag上做同样的事情,以便您可以说getPosts()以获得具有给定Tag的所有帖子。

1

aroth对三个实体的回答是完全有效的,但我们仅使用两个实体做同样的事情,因为第三个实体(即TaggedPost)不会为我们增加任何价值。

我们的实体是这个样子:

@Entity 
@Table(name = "Tag") 
public class Tag { 

    @ManyToMany(fetch=FetchType.LAZY) 
    @JoinTable(
      name="PostTag", 
      [email protected](name="TagId"), 
      [email protected](name="PostId") 
    ) 
    @ForeignKey(name="FK_Tag_Post", inverseName="FK_Post_Tag") 
    private Set<Post> posts; 

    /* ... */ 

} 


@Entity 
@Table(name = "Post") 
public class Post { 

    @ManyToMany 
    @JoinTable(
      name="PostTag", 
      [email protected](name="PostId"), 
      [email protected](name="TagId") 
    ) 
    @ForeignKey(name="FK_Post_Tag", inverseName="FK_Tag_Post") 
    @Sort(comparator=CompareTagByName.class, type=SortType.COMPARATOR) 
    private SortedSet<Tag> tags; 

    /* ... */ 

} 

的优点是,我们不需要手动维护加盟。我们只需根据需要从每个Post中添加或删除Tag

还要注意:

  • 延迟抓取上Tag.posts是个好主意......否则你可能会休眠不必要加载的Post数千每次显示一个标记时间的记录。
  • 许多一对多的加入可以很容易地按照字母顺序排序的标签,通过提供Comparator@Sort注释