Reputation: 15903
I'm trying to implement hashtag functionality in my database, allowing me to assign a hashtag to different classes. Is it possible to have the foreign key inside the tags class, be one of many different classes (Article, Video, Image)? This would mean having a discriminator column.
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
}
In this example I'd be able to run a simple query:
select t.* from tags t where type = 'article' and tagName = 'tag-searching-for'
INNER JOIN Article a ON t.relatedObject = a.articleId;
This would return a bunch of <type-requested>
objects for the type requested (in this case, articles)!
Is there a built in way of doing this with Hibernate or will I have to build my own solution (which Im happy to do, I'd rather check to see if theres a concret one first).
Upvotes: 0
Views: 46
Reputation: 7459
There are two ways, where you can just use a super entity - inheritance.
create Taggable
, a new super entity for Article, Video, ...
@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
{
...
}
make Tag
a super entity
@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<>();
}
In both cases the query you probably will use more often (conversely to the one you brought in example) is something like [JPQL style - not SQL!]:
select a
from Article a
join a.tags t
where t.tagName = 'tag-searching-for'
to get all articles with that specific tagName.
IMHO the first one requires less refactoring and less boilerplate code, but, due to java single-class inheritance limitation, could cause some problem if/when you'll extend your model in the future.
As a side note, I don't see the meaning in using a single relatedObject
, so I changed it to a Set<>
Upvotes: 1