避免在多对一关系中重复

时间:2014-08-31 10:26:26

标签: hibernate

我正在开发一个应用程序,用于存储指定日期的城市天气信息。 我的WeatherInfo类看起来像这样:

@Entity
public class WeatherInfo implements ResponseObject
{
    @Id
    @GeneratedValue
    private int id;

    @Column
    @Temporal(value=TemporalType.TIMESTAMP)
    @JsonProperty("date")
    @JsonSerialize(using=JsonUtils.TimestampSerializer.class)
    private Date date;

    @ManyToOne(cascade=CascadeType.ALL)
    @JsonProperty("city")
    private City city;

    @ManyToMany(cascade=CascadeType.ALL)
    @JsonProperty("weather")
    private Collection<Weather> weather;


    @SuppressWarnings("unused")
    private WeatherInfo()
    {
    //Used by Hibernate
    }

    public WeatherInfo(Date aDate, City aCity,Collection<Weather> aWeatherCollection){
    this.date = aDate;
    this.city = aCity;
    this.weather = aWeatherCollection;

    }

}

问题在于,如果我将给定城市的WeatherInfo保存3次,则同一城市的3个条目将添加到City表中。我假设如果我在WeatherInfo和City之间指定了多对一关系,就不会发生这种情况。我该如何阻止这种情况发生?

更新

我从OpenWeatherMap REST服务获取WeatherInfo,并将他们的City和Weather对象映射到我自己的对象。

public OWMWeatherInfoAdapter(org.openweathermap.WeatherInfo aWeatherInfo)
    {
    super();
    super.setDate(aWeatherInfo.getTimestamp());
    super.setCity(getCity(aWeatherInfo));
    super.setWeather(getWeatherCollection(aWeatherInfo));

    }

    private City getCity((org.openweathermap.WeatherInfo aWeatherInfo){
    Synopsis sys = aWeatherInfo.getSynopsis();
    Coordinate coord = new Coordinate(aWeatherInfo.getCoordinates().getLongitude(),aWeatherInfo.getCoordinates().getLatitude());
    return new City(aWeatherInfo.getCityName(),sys.getCountry(),sys.getSunrise(),sys.getSunset(),coord);
    }

    private Collection<Weather> getWeatherCollection((org.openweathermap.WeatherInfo aWeatherInfo){

    Collection<org.openweathermap.Weather> owmWeathers = aWeatherInfo.getWeathers();
    for(org.openweathermap.Weather owmWeather : owmWeathers){
        super.getWeather().add(new Weather(owmWeather.getMain(),owmWeather.getDescription()));
    }

    return super.getWeather();
    }

1 个答案:

答案 0 :(得分:1)

每次调用时,getCity(WeatherInfo)方法都会返回城市。这意味着如果它被调用3次,它将返回3个不同的城市,最终导致CITY表中的3行。如果getCity(WeatherInfo)返回3个相同的城市,它仍然是3个不同的对象,因此在CITY表中有3行。

为了避免这种情况,您需要在创建新城市的实例之前检查某个城市的实例是否已存在。如果您可以假设没有两个城市可以共享相同的名称,您可以先按名称查找数据库中的城市:

private getCity(WeatherInfo info) {
    Query query = session.createQuery("from City where name = :name"); // assume field session is available
    query.setParameter("name", info.getCityName());
    City city = query.uniqueResult();
    if (city == null) {
        // Only in this case should we create a new City
        Synopsis sys = info.getSynopsis();
        Coordinate coord = new Coordinate(iherInfo.getCoordinates().getLongitude(), info.getCoordinates().getLatitude());
        city = new City(info.getCityName(), sys.getContry(), sys.getSunrise(), coord);
        session.save(city);
    }
    return city;
}