Я разрабатываю приложение для сбора данных о погоде. У меня есть 2 объекта POJO "Местоположение" и "Запись". Местоположение содержит информацию о широте и долготе и текущих погодных условиях, а запись содержит всю информацию о погоде в течение определенного времени для определенного местоположения, таким образом, имея отношение «многие к одному» с местоположением. Определение классов у меня следующее:
Location.java
@Entity
@Table(name = "location")
@NamedQueries( {
@NamedQuery(name = "findLocations", query = "SELECT e FROM Location e ORDER BY e.longitude, e.latitude"),
@NamedQuery(name = "findLocationByLatLong", query = "SELECT e from Location e WHERE e.latitude = :latitude AND e.longitude = :longitude"),
@NamedQuery(name = "findLocationById", query = "SELECT e from Location e WHERE e.id = :id"),
@NamedQuery(name = "deleteLocationById", query= "DELETE Location e WHERE e.id = :id"),
@NamedQuery(name = "updateLocation", query = "UPDATE Location e SET e.lastModifiedDate = :lastModifiedDate WHERE e.id = :id")})
public class Location implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
@Column(name="latitude", nullable=false)
protected String latitude;
@Column(name="longitude", nullable=false)
protected String longitude;
@Column(name="lastModifiedDate")
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
@Column(name="windDirection")
private float windDirection;
@Column(name="windSpeed")
private float windSpeed;
@Column(name="temperature")
private float temperature;
}
И запись.java
@Entity
@Table(name = "weatherdata")
@NamedQueries( {
@NamedQuery(name = "findWeatherRecordById", query = "SELECT e from Record e WHERE e.id = :id"),
@NamedQuery(name = "findWeatherRecords", query = "SELECT e from Record e WHERE e.parent = :parent") })
public class Record implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id")
protected Long id;
@Column(name="mTime")
@Temporal(TemporalType.TIMESTAMP)
private Date mtime;
@Column(name="windDirection")
private float windDirection;
@Column(name="windSpeed")
private float windSpeed;
@Column(name="temperature")
private float temperature;
@ManyToOne(cascade = { CascadeType.ALL }, targetEntity=Location.class, fetch = FetchType.EAGER)
@JoinColumn(name="locationId")
protected Location parent;
}
И мои входящие данные имеют вид:
latitude,longitude,date,winddirection,windspeed,temperature
36.9822,-122.0153,20100907000000.00,158,2.68,20.57
38.1838,-120.54,20100907000000.00,248,0,26.68
38.3495,-121.9688,20100907000000.00,149,0.45,33.9
38.41935,-121.36029,20100907000000.00,322,0.9,33.9
37.91617,-122.286,20100907000000.00,224,0,24.46
38.587,-121.3162,20100907000000.00,315,0,34.46
36.8717,-121.6555,20100907000000.00,294,3.13,18.34
Теперь, когда я получаю запись, я хочу вставить ее в таблицу записей. И так как у меня есть внешний ключ к Location, я также добавлю locationId таблицы Location.
Другое дело, таблица Location не заполнена заранее. Поэтому, когда приходит новая запись, я сначала вставляю ее в таблицу Location, а затем заполняю таблицу Record внешним ключом. И я не хочу дублировать записи местоположения в таблице местоположений. Таблица местоположения также будет содержать самые последние данные о температуре, скорости ветра и направлении ветра, как вы можете видеть.
Для этого я использую следующий код:
Location loc = handler.getLocation(line);
//loc.setTemperature(0);
Location dbLoc = null;
try {
Query q = eManager.createNamedQuery("findLocationByLatLong");
q.setParameter("latitude", loc.getLatitude());
q.setParameter("longitude", loc.getLongitude());
dbLoc = (Location) q.getSingleResult();
} catch (Exception e) {
System.out.println("Location not found! Creating new location");
Logger.getLogger("WeatherRecorderBean.class").log(Level.WARNING, e.getMessage());
}
Record r = handler.getRecord(line);
if(dbLoc!=null) {
r.setParent(dbLoc);
dbLoc.setLastModifiedDate(r.getMtime());//I am doing this so as to know what time the weather change entry is about
dbLoc.setWindDirection(r.getWindDirection());
dbLoc.setWindSpeed(r.getWindSpeed());
dbLoc.setTemperature(r.getTemperature());
eManager.merge(r);
}
else {
dbLoc = new Location();
dbLoc.setLatitude(loc.getLatitude());
dbLoc.setLongitude(loc.getLongitude());
//eManager.persist(dbLoc);
r.setParent(dbLoc);
dbLoc.setLastModifiedDate(r.getMtime());
dbLoc.setWindDirection(r.getWindDirection());
dbLoc.setWindSpeed(r.getWindSpeed());
dbLoc.setTemperature(r.getTemperature());
eManager.merge(r);
//eManager.merge(dbLoc);
}
Но, делая это, происходит дублирование локаций. Это означает, что у меня есть несколько записей для одной и той же долготы и широты, но с разной температурой, данными о скорости ветра в таблице местоположений. Я хочу создать единую запись для одной широты и долготы и обновить поля скорости ветра, температуры и направления ветра самыми последними данными.
Пожалуйста, ПОМОГИТЕ!