Hibernate允许外键是多个类之一?

时间:2016-08-29 01:05:52

标签: mysql hibernate

我试图在我的数据库中实现 hashtag 功能,允许我为不同的类分配一个#标签。是否可以在tags类中包含外键,是多个不同类(Article,Video,Image)中的一个?这意味着要有一个鉴别器列。

E.g

@Entity
@Table(name="tags")
public class Tags {
    private String tagName; // the hashtag name; E.g cool-photo
    private <Article, Video, Photo> relatedObject; 
    private String type; // Can either be Article, Video, Photo
}

在此示例中,我可以运行简单的查询:

select t.* from tags t where type = 'article' and tagName = 'tag-searching-for' 
INNER JOIN Article a ON t.relatedObject = a.articleId;

这将为所请求的类型(在本例中为文章)返回一堆<type-requested>个对象!

使用Hibernate是否有内置的方法可以做到这一点,或者我必须构建自己的解决方案(我很乐意这样做,我宁愿先检查一下是否有一个具体的解决方案)。

1 个答案:

答案 0 :(得分:1)

有两种方法,你可以使用超级实体 - 继承。

  1. 创建Taggable,这是文章,视频的新超级实体......

    @Entity
    public class Tag 
    {
        private String tagName; // the hashtag name; E.g cool-photo
    
        @ManyToMany
        @JoinTable(...)
        private Set<Taggable> relatedObjects = new LinkedHashSet<>(); 
    }
    
    @Entity
    @Inheritance(...)
    public abstract class Taggable
    {
        @ManyToMany(mappedBy = "relatedObjects")
        protected Set<Tag> tags = new LinkedHashSet<>();
    }
    
    @Entity
    public class Article extends Taggable 
    {
        ...
    }
    
  2. 使Tag成为超级实体

    @Entity
    @Inheritance(...)
    public abstract class Tag 
    {
        protected String tagName; // the hashtag name; E.g cool-photo
    }
    
    @Entity
    public class ArticleTag extends Tag
    {
        @ManyToMany(mappedBy = "tags")
        private Set<Article> articles = new LinkedHashSet<>();
    }
    
    @Entity
    public class Article
    {
        @ManyToMany
        @JoinTable(...)
        private Set<ArticleTag> tags = new LinkedHashSet<>();
    }
    
  3. 在这两种情况下,您可能会更频繁地使用的查询(与您带来的示例相反)类似于[JPQL样式 - 而不是SQL!]:

    select a 
    from Article a
        join a.tags t
    where t.tagName = 'tag-searching-for' 
    

    获取具有该特定tagName的所有文章。

    恕我直言,第一个需要更少的重构和更少的样板代码,但是,由于java单类继承限制,如果/当你将来扩展你的模型时可能会引起一些问题。

    作为旁注,我没有看到使用单个relatedObject的含义,因此我将其更改为Set<>