我正在开发一个应用程序,用于存储指定日期的城市天气信息。 我的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();
}
答案 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;
}