没有第三张桌子的一对多协会

时间:2013-12-13 13:24:40

标签: java hibernate jpa orm

好的,今天我尝试了一个基本的Hibernate教程,我很难让它按照我想要的方式运行。

这是一个简单的片段,假设所有其他字段/方法都已定义(例如id等)

@Entity
@Table(name = "CITIES")
public static class City {

    @ManyToOne
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Country country;


}


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

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<City> cities;
}

上述解决方案使用(自动创建的)关联表 - COUNTRY_CITIES,但是 这只能以一种方式起作用 - 即我看到国家的城市(当我选择一个城市时),但我看不到城市的国家(当我选择一个城市时)。

那么我该怎样做才能让城市看到他们的国家呢?

我可以在@JoinColumn(name = "COUNTRY_ID")字段中添加Country.cities,但它有两种方式。

但我不想从国家/地区代码中向城市表中添加列。

所以我将@JoinColumn添加到了City.country字段,但它没有用。

那么 - 如何使协会以两种方式工作,而没有一个关联表?


好的,确切地说:我使用上面的代码为这个对象添加了数据库:

    Country germany = new Country("Germany", new HashSet<>(asList(
            new City("Berlin"),
            new City("Hamburg")
    )));

..并查看了数据库。它看起来像这样:

表COUNTRIES_CITIES (注意,我没有声明它; Hibernate会自动执行)

COUNTRIES_ID   CITIES_ID  
1              1
1              2

表国家/地区

ID      NAME  
1       Germany

表CITIES (注意我没有声明COUNTRY_ID列!再次Hibernate ..)

ID   NAME      COUNTRY_ID  
1    Berlin    null
2    Hamburg   null

就是这样。获取国家给了我城市,取得城市给了我无国家。


如果我向@JoinColumn类添加Country,那么a列将附加到CITIES表,并且提取工作有两种方式。

3 个答案:

答案 0 :(得分:3)

看完你的编辑问题后很清楚。

您添加城市并与国家/地区相关联的方式......

Country germany = new Country("Germany", new HashSet<>(asList(
        new City("Berlin"),
        new City("Hamburg")
)));

如果你这样做,那么City没有国家。不,你在哪里设置城市的国家财产。即。 city.country = germany;
双向关系中,您不能依赖JPA或您的提供商来完全管理对象持久性。

所以这就是你需要做的......

Country germany = new Country("Germany");
City berlin = new City("Berlin");
City Hamburg = new City("Hamburg");
berlin.country = germany;
hamburg.country = germany;
germany.cities = new HashSet<>(asList(berlin, hamburg));
germany.saveOrUpdate(); // or whichever definition you use

现在在数据库中,您的城市表将具有正确的国家/地区ID。 此外,由于这是一种双向关系,因此建议您使用mappedBy关系中的@OneToMany属性。使用它,你告诉JPA城市是Country 1-n City关系的反面。

答案 1 :(得分:2)

您是否尝试过使用mappedBy属性?

@OneToMany(mappedBy="country", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<City> cities;

有关说明,请查看此处:Can someone please explain mappedBy in hibernate?

答案 2 :(得分:0)

第1步:在OneToMany端添加mappingBy。

 @OnetoMany(mappedBy="users")
   private List<Address> address;

第2步:在ManyToOne端添加JoinColumn。

 @ManytoOne
 @JoinColumn("userId")
 private User user;