Search code examples
javajpaentity-relationshipone-to-many

JPA : defining a complex @OneToMany relationship


I've defined a set of tables t1, t2, ... tN:

mysql>  desc t1;
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
(...)
+-------------+------------------+------+-----+---------+----------------+

(...)

mysql>  desc tN;
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
(...)
+-------------+------------------+------+-----+---------+----------------+

and a table that will store some comments about each records in the tables t1, ... tN:

 mysql> desc postit;

+---------------+------------------+------+-----+---------+----------------+
| Field         | Type             | Null | Key | Default | Extra          |
+---------------+------------------+------+-----+---------+----------------+
| id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| foreign_id    | int(10) unsigned | NO   | MUL | NULL    |                |
| foreign_table | varchar(20)      | NO   | MUL | NULL    |                |
| content       | text             | NO   |     | NULL    |                |
(....)
+---------------+------------------+------+-----+---------+----------------+

Now how should I define an @Entity for the table 't1' ....

@Entity(name="T1")
@Table(name="t1")
public class T1
    {
        (...)
        public List<PostIt> getComments() { ... }
        }

to retrieve all its comments from the table 'postit' as the expression should be

select P from postit as P where P.foreign_table="t1" and P.foreign_id= :t1_id

Is there a specific JPA annotation to define this relation or should I inject (how?) an EntityManager in each instance of T1 and call a @NamedQuery ?


Solution

  • Your design corresponds to an inheritance tree, where all the subclasses of the root AbstractComment entity would be stored in the same table, using a discriminator column (foreign_table):

    @Entity
    @Table(name = "postit")
    @Inheritance(strategy = SINGLE_TABLE)
    @DiscriminatorColumn(name = "foreign_table", discriminatorType = STRING)
    public abstract class AbstractComment {
        // ... fields, getters, setters
    }
    
    @Entity
    @DiscriminatorValue("t1")
    public class T1Comment extends AbstractComment {
    
    }
    
    @Entity
    @Table(name="t1")
    public class T1 {
        @OneToMany
        @JoinColumn(name = "foreign_id")
        private Set<T1Comment> comments;
    }