Comment gérer JPA Plusieurs-à-Un Rapport?
Je suis en train de concevoir une application pour la collecte de données météorologiques. J'ai 2 objets POJO "Emplacement" et "Enregistrer". Emplacement contient des informations à propos de la latitude et de la longitude et de la météo, et le Dossier contient toutes les informations météo au fil du temps un lieu spécifique ayant ainsi une many-to-one relation avec l'Emplacement. La définition des classes que j'ai est comme suit:
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;
}
Et Record.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;
}
Et mes données entrantes est dans la forme de:
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
Maintenant, chaque fois que je reçois un record, je veux l'insérer dans l'Enregistrement de la table. Et comme j'ai une clé étrangère pour l'Emplacement, je vais aussi ajouter le locationId de l'Emplacement de la table.
Une autre chose, l'Emplacement de la table n'est pas prédéfinie. Donc, chaque fois qu'un nouveau dossier vient j'ai d'abord l'insérer dans l'Emplacement de la table, puis de renseigner le Dossier de la table avec la clé étrangère. Et je ne veux pas la duplication des entrées d'emplacement en Emplacement de la table. Emplacement table contiendra également les plus récentes de la température, la vitesse du vent et de winddirection de données comme vous pouvez le voir.
Je suis en utilisant le code suivant à faire:
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);
}
Mais en faisant cela, ce qui se passe est sites sont dupliqués. Sens-je avoir plusieurs entrées pour le même longitude et de la latitude, mais avec différentes température, la vitesse du vent données à l'Emplacement de la table. Ce que je veux accomplir est d'avoir une entrée unique pour une latitude et de la longitude et de la mise à jour de la vitesse du vent, de la température et de winddirection champs avec les données les plus récentes.
S'il vous plaît AIDER!
Vous devez vous connecter pour publier un commentaire.
Vous êtes en cascade
ALL
opérations deRecord
àLocation
ainsi, lorsque vous fusionnez un nouveauRecord
et son nouveau parentLocation
, il n'est pas nécessaire de fusionner un transitoireLocation
de nouveau (ou vous aurez des lignes dupliquées).J'ai mis quelques commentaires dans votre code ci-dessous (je n'ai pas tout régler, il y a de l'OMI, plus de problèmes, mais les modifications proposées devraient au moins supprimer les doublons
Location
entrées):Résolu 🙂
Je créer une nouvelle fonction pour enregistrer
Location
.J'ai aussi eu quelques problèmes de synchronisation. J'ai eu cette fonction dans un MDB
onMessage()
fonction. Donc, avant unonMessage()
était fini, un autre a commencé en créant des entrées en double!Espère que cela aide quelqu'un dans le futur!