在hibernate中持久化oneToMany和manyToOne关系中的对象的问题

时间:2011-09-09 13:12:27

标签: hibernate spring persistence

我有一个与hibernate相关的疑问...如果我有跟随scenerio

@Entity
@Table(name="CONTINENT")
public class Continent {

@Id
@GeneratedValue
private Integer id;


private String name;


@OneToMany(cascade = {CascadeType.ALL}, fetch=FetchType.EAGER)
@JoinColumn(name = "CONTI_ID")
private Set<Country> countries;
public Continent() {

}

以下是我的国家课程

    @Entity
    @Table(name="COUNTRY")
    public class Country {

        @Id
        @GeneratedValue
        //@Column(name="CTRY_ID")
        private Integer id;

        @Column(name="CTRY_NAME")
        private String name;

        private int area;

        @ManyToOne
        @JoinColumn(name = "CONTI_ID")
        private Continent continent;

        @Enumerated(EnumType.STRING)
        private LanguageSpoken lang;
}

我正在尝试执行以下

updateCountry(){
Continent c1 = new Continent();
Country c = getNewCountry(c1);
c.setArea("berlin");
continentDao.update(c1);// **will child's location be set in db????**
c.getId().equals(1);//**If above questions answer is yes then why it throws null pointer exception**
}


getNewCountry(c1){
Country c = new Country();
c.setName("germany");
c1.getCountry().add(c);
continentDao.update(c1);
}

有人可以帮助我理解评论中的问题 为什么我在这条线上得到Null Pointer c.getId()

2 个答案:

答案 0 :(得分:1)

在双向关系中,您必须连接关系的两侧。在这里,您只连接了一侧

c1.getCountry().add(c);

您还需要连接相反的关系,即

c.setContinent(c1);

此外,c.getId()可能为null,因为您已将其设置为GeneratedValue并且尚未保留。因此,在关系的两个方面都要接线。

答案 1 :(得分:1)

在任何双向关系中,你应该选择一方作为拥有方。这是通过设置“mappedBy”属性来完成的。通常,这将在一对多方面(在您的情况下为大陆)完成。如果映射正确,您将在保存时避免国家与大陆之间的任何争用。

问题的第二部分正是RationalSpring所提到的。修改双向关系的一侧并保存它将更新数据库中的记录,但不会更新已加载的任何对象图。出于这个原因,通常最好有一个负责管理对象图的服务方法。在你的情况下,它将确保正确设置国家和大陆之间的双向链接,然后你将保存关系的拥有方。