JPA:定义复杂的@OneToMany关系

时间:2012-05-30 09:23:49

标签: java jpa entity-relationship one-to-many

我已经定义了一组表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 |
(...)
+-------------+------------------+------+-----+---------+----------------+

和一个表格,用于存储关于表格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    |                |
(....)
+---------------+------------------+------+-----+---------+----------------+

现在我应该如何为表't1'....

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

从表'postit'中检索其所有注释,因为表达式应为

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

是否有特定的JPA注释来定义这种关系,还是应该在每个T1实例中注入(如何?) EntityManager 并调用@NamedQuery?

2 个答案:

答案 0 :(得分:2)

我认为你应该使用inheritance建模表。

这样你就有了AbstractTable

@Entity
@DiscriminatorColumn(name="type_id")
@DiscriminatorValue("-1")
...
class AbstractTable {

@OneToMany(mappedBy="foreign_id")
public List<PostIt> getComments() { ... }
        }
...
}

还有:

@Entity
@DiscriminatorValue("1")
...
class Table1 {}

@Entity
@DiscriminatorValue("2")
...
class Table2 {}

如果您需要双向关系,那么您需要弄清楚如何从Postit实体引用到表。我觉得像是

@ManyToOne
public AbstractTable getTable() { ... }

应该有用。

可在此处找到更多信息http://wleeper.com/2009/12/17/jpa-onetomany-with-inheritance/

答案 1 :(得分:1)

您的设计对应于继承树,其中根AbstractConment实体的所有子类将使用鉴别器列(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;
}