سؤال

أقوم بتصميم طلب لجمع بيانات الطقس. لديّ 2 كائنات pojo "موقع" و "سجل". يحتوي الموقع على معلومات حول خطوط الطول والعرض والظروف الجوية الحالية ، ويحتوي السجل على جميع معلومات الطقس بمرور الوقت لموقع معين وبالتالي وجود علاقة كثيرة مع الموقع. تعريف الفصول التي لدي على النحو التالي:

الموقع

@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;
}

و 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;
}

وبياني الواردة في شكل:

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

الآن كلما حصلت على سجل ، أريد إدراجه في جدول التسجيلات. وبما أن لدي مفتاحًا خارجيًا للموقع ، فسوف أضيف أيضًا موقع Tore of Morke Table. شيء آخر ، جدول الموقع غير مُصنوع مسبقًا. لذلك عندما يأتي سجل جديد ، أقوم بإدخاله أولاً في جدول الموقع ، ثم قم بملء جدول التسجيل بالمفتاح الخارجي. وأنا لا أريد إدخالات موقع التكرار في جدول الموقع. سيحتوي جدول الموقع أيضًا على أحدث بيانات درجات الحرارة و Speedspeed و Winddirection كما ترون.

أنا أستخدم الكود التالي لإنجاز ذلك:

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);

}

ولكن من خلال القيام بذلك ، ما يحدث هو تكرار المواقع. وهذا يعني أن لدي إدخالات متعددة لنفس خط الطول وخطوط العرض ولكن مع درجة حرارة مختلفة ، بيانات سرعة الرياح في جدول الموقع. ما أريد إنجازه هو الحصول على إدخال واحد لضطرفي وخط الطول واحد وتحديث حقول Windspeed و Terge و Winddirection مع أحدث البيانات.

الرجاء المساعدة!

هل كانت مفيدة؟

المحلول 2

تم حلها :-)

public Location saveLocation(Location loc) {
    eManager.clear();
    eManager.setFlushMode(FlushModeType.COMMIT);
    //eManager.setFlushMode(FlushModeType.COMMIT);
    Query q = eManager.createNamedQuery("findLocationByLatLong");
    q.setParameter("latitude", loc.getLatitude());
    q.setParameter("longitude", loc.getLongitude());
    try {
        Location dummy = (Location) q.getSingleResult();
        eManager.clear();
        // eManager.flush();
        return dummy;
    } catch (NoResultException ex) {
        Logger.getLogger("WeatherRecorderBean.class").log(Level.WARNING,
                ex.getMessage());
        eManager.clear();
        eManager.merge(loc);
        eManager.flush();
        return loc;
    } catch (Exception ex) {
        Logger.getLogger("WeatherRecorderBean.class").log(Level.WARNING, "Should never get here! "+ex.getMessage());
        return null;
    }
}

أقوم بإنشاء وظيفة جديدة للحفظ Location. كان لدي أيضا بعض مشاكل التزامن. كان لدي هذه الوظيفة في MDB onMessage() وظيفة. لذلك قبل واحد onMessage() تم الانتهاء من آخر بدأ واحد ومن ثم إنشاء إدخالات مكررة!

آمل أن يساعد هذا شخص ما في المستقبل!

نصائح أخرى

أنت متتالي ALL العمليات من Record إلى Location لذلك عندما تندمج جديد Record و والدها الجديد Location, ، ليست هناك حاجة لدمج عابرة Location مرة أخرى (أو ستحصل على خطوط مكررة).

لقد وضعت بعض التعليقات في الكود الخاص بك أدناه (لم أصلح كل شيء ، وهناك المزيد من المشكلات ، لكن التغييرات المقترحة يجب أن تزيل على الأقل إنشاء التكرارات Location إدخالات):

if(dbLoc==null) {
  dbLoc = new Location();
  dbLoc.setLatitude(loc.getLatitude());
  dbLoc.setLongitude(loc.getLongitude());
  r.setParent(dbLoc);

  // add changes on the dbLoc here

  eManager.merge(r);  // here you're merging r and the dbLoc 

  //loc.setLastModifiedDate(r.getMtime()); // why are you modifying the line from the file?
  //loc.setWindDirection(r.getWindDirection());
  //loc.setWindSpeed(r.getWindSpeed());
  //loc.setTemperature(r.getTemperature());
  //eManager.persist(loc);    
  //System.out.println("Location id : "+loc.getId());

  //eManager.merge(dbLoc); // here you're merging a transient dbLoc again

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top