Hibernate OnetoMany,ManyToOne Mapping赋予null

时间:2013-03-08 05:19:04

标签: java hibernate jpa

我有2个名为PurchaseList.java和PurchaseListItems.java的类

我必须在PurchaseListItems中映射PurchaseList

PurchaseList.java

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name="pl_id",referencedColumnName="id")
private List<PurchaseListItems> purchaseListItems;

PurchaseListItems.java

@ManyToOne
@JoinColumn(name="pl_id")
private PurchaseList purchaseListId;

一切都很好但是我在pl_id中得到了null。请告诉我哪里错了

7 个答案:

答案 0 :(得分:5)

您的映射实际上定义了两个独立的单向关系。你想要的是一个双向关系。下面的代码将建立双向关系

@OneToMany(cascade = CascadeType.ALL, mappedBy = "purchaseListId")
@JoinColumn(name="pl_id",referencedColumnName="id")
private List<PurchaseListItems> purchaseListItems;

mappedBy属性是必需的,因为提供程序无法自动确定指定的关系实际上形成单个关系。可以使用实例成员的Java类型,但如果您有多个相同类型的成员,那该怎么办呢?在很多情况下,你有两个单一的关系。例如:

OneToMany:用户 - &gt; ForumThread(用户创建的线程)

ManyToOne:ForumThread - &gt;用户(关闭线程的用户。显然不一定是启动线程的用户)

这是两个独立的关系,必须这样对待。如果你的持久性只是因为类型和多重性匹配而提供了双向关系,你会感到非常惊讶。

另请注意,双向关系不会由任何JPA提供程序自动管理,这意味着反面不会在对象模型中自动更新/设置,因此不会在数据库中自动更新/设置。你必须自己做。顺便说一句,在我的所有项目中,双向关系是一种痛苦,我认为避免它们是明智的。

答案 1 :(得分:2)

由于某种原因,我没有使用postgres sql和Hibernate4为我工作

在映射下工作

<强> PurchaseList.java

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name="pl_id",nullable=false)
private List<PurchaseListItems> purchaseListItems;

<强> PurchaseListItems.java

@ManyToOne
@JoinColumn(name="pl_id", nullable=false,insertable=false,updatable=false )
private PurchaseList purchaseListId;

注意:您必须使用Identity或明确提及postgres的id列的序列。

@GeneratedValue(strategy=GenerationType.IDENTITY)

答案 2 :(得分:0)

jpa规范看起来不错,但验证您是否在数据库中提供了有效的父对子关系。如果没有引用,那么它将返回null。

答案 3 :(得分:0)

试试这个

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "purchaseListId")

答案 4 :(得分:0)

在创建时,检查是否已使用有效值(已创建的 PurchaseList 实例)填充 purchaseListId PurchaseListItems 值。

最好使用 mappedBy 作为以下代码,让多方来维持这种关系。

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "purchaseListId")
@JoinColumn(name="pl_id",referencedColumnName="id")
private List<PurchaseListItems> purchaseListItems;

答案 5 :(得分:0)

for(PurchaseListItems item:purchaseListItemsList)
item.purchaseListId(PurchaseList);

这是我在创建对象时错过的。

为你的答案着想

答案 6 :(得分:0)

  1. @JoinColumn注释属于关系的@ManyToOne一侧 - 但不在@OneToMany方面 - 从@OneToMany方面删除它。

  2. Cascade用于级联DELETE / READ / UPDATE操作...,但它不会自动填充外键“子”侧的ID列。实际上,它不会填充对FK关系两侧的对象的java引用。您需要在双向关系的两端手动设置关系数据:

    myPurchaseListItem.setPurchaseList(myPurchaseList);
    myPurchaseList.setPurchaseListItem(myPurchaseListItem);

    来自JPA 2规范:

    托管实体之间的双向关系将根据关系所属方持有的引用进行保留。开发人员有责任保持内存引用保持在拥有方,而保持在反方的引用在更改时保持一致。在单向一对一和一对多关系的情况下,开发人员有责任确保(原文如此)遵守关系的语义。[29]

    特别重要的是要确保对关系的反面进行更改会在拥有方进行适当的更新,以确保更改在与数据库同步时不会丢失。