如何在 JPA 中定义单向 OneToMany 关系

Posted

技术标签:

【中文标题】如何在 JPA 中定义单向 OneToMany 关系【英文标题】:How to define unidirectional OneToMany relationship in JPA 【发布时间】:2012-08-15 19:49:06 【问题描述】:

JPA 中的实体映射存在以下问题。我有两个实体,第一个是查找,第二个是代表实体翻译的文本。现在我需要将 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;

所以我尝试了这个(以及其他一些变体)但没有结果。我也无法在数据库中创建连接表,我不想将 Lookup 绑定到我的 Text 类。那么有没有其他方法可以告诉我吗?

【问题讨论】:

【参考方案1】:

我的 JPA 工作圣经是Java Persistence wikibook。它有一个section 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;

【讨论】:

哇,真的有效,谢谢。我认为如果关系只有一侧(另一侧不持有外键),我总是需要创建一个连接表。 宾果游戏!这个“Java Persistence Wikibook”链接是我一直在寻找的……感谢分享…… 我也在尝试相同的方法,但是在数据库的子实体中没有设置外键,我遇到了这个异常:oracle.jdbc.OracleDatabaseException: ORA-01400: cannot insert NULL into @SandeepKumar “子实体”是什么意思?在这个例子中相当于Text?我怀疑 JPA 不认为引用的列是外键,在这种情况下,它不会用父 ID 填充它;恐怕你必须在保存前自己设置。 我通过从我的子类中删除该属性解决了这个问题。现在,JPA 正在隐式考虑父类中提到的键并插入值。谢谢!

以上是关于如何在 JPA 中定义单向 OneToMany 关系的主要内容,如果未能解决你的问题,请参考以下文章

java JPA中的单向OneToMany关系

Entity-Bean (JPA) 中的单向关系

OneToMany 和 ManyToMany 单向关系的区别

JPA 与同一实体的两个单向 @OneToMany 关系导致重复条目

JPA与同一实体的两个单向@OneToMany关系导致重复输入

JPA 单向一对多关联关系