Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA polymorphic oneToMany

I couldn't figure out how to cleanly do a tag cloud with JPA where each db entity can have many tags.

E.g

Post can have 0 or more Tags User can have 0 or more Tags

Is there a better way in JPA than having to make all the entities subclass something like Taggable abstract class? Where a a Tag entity would reference many Taggables.

Edit: the tag cloud is just a sample to simplify the problem I am having. In my scenario, the relation should be OneToMany where a Tag cannot be reused.

thank you

like image 601
bob Avatar asked Nov 06 '22 12:11

bob


2 Answers

This seems like ManyToMany, not one to Many. Users can have multiple tags, and a tag can be associated with more than one user?

You would only need such a superclass if you want to be able to have a relationship on your Tag to a single collection that contains every object marked with that tag. Do you have a requirement for a tag.getOneGiantCollectionOfEveryTaggedEntity() method?

Since the marked objects don't seem to otherwise have anything in common, does such a collection really have any value in your application domain? It could also ostensibly be quite large and not something you'd really want to work with via object relationships anyway. From a practical standpoint, without knowing about your use case, it seems like tag.getTaggedUsers(), tag.getTaggedPosts() etc are more useful.

Sorry, guess I'm asking more questions than giving answers, but it's not clear what you want your finished object domain to look like :)

edit:

Maybe the actual answer then to the question asked is just "No, Hibernate will not map for you you a Raw Collection of types with no common ancestor that just happen to all have foreign keys to your entity." You don't neccessarily have to impose a 'fake' superclass on your entities, but if you don't then you'll have to make a join table.

.?

like image 111
Affe Avatar answered Nov 12 '22 17:11

Affe


Is there a better way in JPA than having to make all the entities subclass something like Taggable abstract class?

Let's forget the example :) JPA does support polymorphic associations but the target classes have to be part of an inheritance hierarchy. And here are some more rules of thumb about inheritance strategies:

  • SINGLE_TABLE:
    • All the classes in a hierarchy are mapped to a single table
    • This strategy provides good support polymorphic relationships between entities and queries that cover the entire class hierarchy.
    • May contain null fields for some subclass data
  • TABLE_PER_CLASS:
    • Each class in a hierarchy mapped to a separate table and hence, provides poor support for polymorphic relationships
    • requires SQL union or separate SQL queries for each subclass
  • JOINED
    • no null fields => compact data
    • This provides good support for polymorphic relationships, but requires one or more join operations – may result in poor performance

In short, if your subclasses declare relatively few properties, prefer the SINGLE_TABLE strategy. If not, use a JOINED strategy unless you have a deep hierarchy (in which case the cost of joins may become more expensive than unions and then TABLE_PER_CLASS would be "less worse").

References

  • JPA 1.0 Specification
    • Section 2.1.9 "Inheritance"
    • Section 2.1.10 "2.1.10 Inheritance Mapping Strategies"
like image 45
Pascal Thivent Avatar answered Nov 12 '22 15:11

Pascal Thivent