如何在JPA中定义一对多的单向关系

84

我在JPA中使用实体映射时遇到了以下问题。我有两个实体,第一个是Lookup,第二个是Text,表示实体的翻译。现在我需要将Lookup绑定到Text,但我不想让Text引用Lookup。更复杂的是,Text在这种关系中不使用其主键,而是在TXTHEAD_CODE列中定义的元代码。

Lookup.java

@Entity
@Table(name = "DATREG")
public class Lookup implements PersistableEntity {

    @Id
    @Column(name = "DATREG_META_CODE")
    private String metaCode;

    @OneToMany
    @JoinTable(name="TXT", 
            joinColumns=@JoinColumn(name="DATREG_META_CODE", referencedColumnName="TXTHEAD_CODE"),
            inverseJoinColumns=@JoinColumn(name="DATREG_META_CODE"))
    private List<Text> text;

Text.java

@Entity
@Table(name = "TXT")
public class Text {

    @Id
    @Column(name = "TXT_ID")
    private Long id;

    @Column(name = "TXTHEAD_CODE")
    private String code;

我尝试了这个方法(以及其他几种变化),但没有结果。我也无法在数据库中创建联接表,也不想将查找绑定到我的Text类。所以请问是否有其他方法?

1个回答

174
我的JPA工作圣经是Java Persistence wikibook。它有一篇关于单向OneToManysection on unidirectional OneToMany,其中解释了如何使用@JoinColumn注释来完成此操作。在你的情况下,我认为你会想要:
@OneToMany
@JoinColumn(name="TXTHEAD_CODE")
private Set<Text> text;

我使用了一个Set而不是List,因为数据本身没有顺序。
上面使用了一个默认的referencedColumnName,与wikibook中的示例不同。如果这样不起作用,请尝试显式指定一个:
@OneToMany
@JoinColumn(name="TXTHEAD_CODE", referencedColumnName="DATREG_META_CODE")
private Set<Text> text;

哇,真的成功了,谢谢。我以为如果关系只有一边(另一边不持有外键),我总是需要创建一个连接表。 - Petr Mensik
6
太棒了!这个“Java持久化Wikibook”的链接正是我一直在找的...感谢你的分享... - Ahmet
我正在尝试做同样的事情,但是在数据库中子实体中的外键没有被设置,我得到了这个异常:oracle.jdbc.OracleDatabaseException: ORA-01400: cannot insert NULL into - Sandeep Kumar
@SandeepKumar,“child entity”是什么意思?在这个例子中的“Text”的等价物是什么?我怀疑JPA不会认为所引用的列是一个外键,因此它不会用父级的ID填充它;我担心在保存之前你将不得不自己设置它。 - Tom Anderson
1
我通过从我的子类中删除该属性来解决了这个问题。现在,JPA会隐式地考虑到父类中提到的键并插入值。谢谢! - Sandeep Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接