I thought that it might be helpful to others (and myself) if I detailed my thoughts and learning process as I work through the issues.
The first step I took was to reverse engineer the database using hibernate. This gives me several classes. They are as follows:
Instruments.java: This is the class that identifies which instruments are doing the measuring
Code:
package org.hibernate.timeseries;
// Generated Jun 17, 2008 11:33:48 PM by Hibernate Tools 3.2.1.GA
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* Instruments generated by hbm2java
*/
@Entity
@Table(name="instruments"
,schema="weather"
)
public class Instruments implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -8742383364804218579L;
private int id;
private String description;
private Set<Timeseries> timeseriesesForLocationId = new HashSet<Timeseries>(0);
private Set<Timeseries> timeseriesesForInstrumentId = new HashSet<Timeseries>(0);
public Instruments() {
}
public Instruments(int id, String description) {
this.id = id;
this.description = description;
}
public Instruments(int id, String description, Set<Timeseries> timeseriesesForLocationId, Set<Timeseries> timeseriesesForInstrumentId) {
this.id = id;
this.description = description;
this.timeseriesesForLocationId = timeseriesesForLocationId;
this.timeseriesesForInstrumentId = timeseriesesForInstrumentId;
}
@Id
@Column(name="id", unique=true, nullable=false)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="description", nullable=false, length=120)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="instrumentsByLocationId")
public Set<Timeseries> getTimeseriesesForLocationId() {
return this.timeseriesesForLocationId;
}
public void setTimeseriesesForLocationId(Set<Timeseries> timeseriesesForLocationId) {
this.timeseriesesForLocationId = timeseriesesForLocationId;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="instrumentsByInstrumentId")
public Set<Timeseries> getTimeseriesesForInstrumentId() {
return this.timeseriesesForInstrumentId;
}
public void setTimeseriesesForInstrumentId(Set<Timeseries> timeseriesesForInstrumentId) {
this.timeseriesesForInstrumentId = timeseriesesForInstrumentId;
}
}
Locations.java: This is the class that contains information about the locations where the measurements are being done
Code:
package org.hibernate.timeseries;
// Generated Jun 17, 2008 11:33:48 PM by Hibernate Tools 3.2.1.GA
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Locations generated by hbm2java
*/
@Entity
@Table(name="locations"
,schema="weather"
)
public class Locations implements java.io.Serializable {
private int id;
private String description;
public Locations() {
}
public Locations(int id, String description) {
this.id = id;
this.description = description;
}
@Id
@Column(name="id", unique=true, nullable=false)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="description", nullable=false, length=120)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
}
Measurements.java: This is the class that contains information about the time of day/type of measurement that is being done
Code:
package org.hibernate.timeseries;
// Generated Jun 17, 2008 11:33:48 PM by Hibernate Tools 3.2.1.GA
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* Measurements generated by hbm2java
*/
@Entity
@Table(name="measurements"
,schema="weather"
)
public class Measurements implements java.io.Serializable {
private int id;
private String description;
private Set<Timeseries> timeserieses = new HashSet<Timeseries>(0);
public Measurements() {
}
public Measurements(int id, String description) {
this.id = id;
this.description = description;
}
public Measurements(int id, String description, Set<Timeseries> timeserieses) {
this.id = id;
this.description = description;
this.timeserieses = timeserieses;
}
@Id
@Column(name="id", unique=true, nullable=false)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="description", nullable=false, length=120)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="measurements")
public Set<Timeseries> getTimeserieses() {
return this.timeserieses;
}
public void setTimeserieses(Set<Timeseries> timeserieses) {
this.timeserieses = timeserieses;
}
}
Finally there are the classes that are associated with our actual timeseries table. It is a link table. Two classes are generated. One is called TimeseriesID.java which is the class that wraps the composite primary key of the table
Code:
package org.hibernate.timeseries;
// Generated Jun 17, 2008 11:33:48 PM by Hibernate Tools 3.2.1.GA
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Embeddable;
/**
* TimeseriesId generated by hbm2java
*/
@Embeddable
public class TimeseriesId implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 4880400296435235114L;
private int locationId;
private int measurementId;
private int instrumentId;
private Date datetime;
public TimeseriesId() {
}
public TimeseriesId(int locationId, int measurementId, int instrumentId, Date datetime) {
this.locationId = locationId;
this.measurementId = measurementId;
this.instrumentId = instrumentId;
this.datetime = datetime;
}
@Column(name="location_id", nullable=false)
public int getLocationId() {
return this.locationId;
}
public void setLocationId(int locationId) {
this.locationId = locationId;
}
@Column(name="measurement_id", nullable=false)
public int getMeasurementId() {
return this.measurementId;
}
public void setMeasurementId(int measurementId) {
this.measurementId = measurementId;
}
@Column(name="instrument_id", nullable=false)
public int getInstrumentId() {
return this.instrumentId;
}
public void setInstrumentId(int instrumentId) {
this.instrumentId = instrumentId;
}
@Column(name="datetime", nullable=false, length=13)
public Date getDatetime() {
return this.datetime;
}
public void setDatetime(Date datetime) {
this.datetime = datetime;
}
public boolean equals(Object other) {
if ( (this == other ) ) return true;
if ( (other == null ) ) return false;
if ( !(other instanceof TimeseriesId) ) return false;
TimeseriesId castOther = ( TimeseriesId ) other;
return (this.getLocationId()==castOther.getLocationId())
&& (this.getMeasurementId()==castOther.getMeasurementId())
&& (this.getInstrumentId()==castOther.getInstrumentId())
&& ( (this.getDatetime()==castOther.getDatetime()) || ( this.getDatetime()!=null && castOther.getDatetime()!=null && this.getDatetime().equals(castOther.getDatetime()) ) );
}
public int hashCode() {
int result = 17;
result = 37 * result + this.getLocationId();
result = 37 * result + this.getMeasurementId();
result = 37 * result + this.getInstrumentId();
result = 37 * result + ( getDatetime() == null ? 0 : this.getDatetime().hashCode() );
return result;
}
}
and Timeseries.java which is the class that represents an row of the table
Code:
package org.hibernate.timeseries;
// Generated Jun 17, 2008 11:33:48 PM by Hibernate Tools 3.2.1.GA
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Embeddable;
/**
* TimeseriesId generated by hbm2java
*/
@Embeddable
public class TimeseriesId implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 4880400296435235114L;
private int locationId;
private int measurementId;
private int instrumentId;
private Date datetime;
public TimeseriesId() {
}
public TimeseriesId(int locationId, int measurementId, int instrumentId, Date datetime) {
this.locationId = locationId;
this.measurementId = measurementId;
this.instrumentId = instrumentId;
this.datetime = datetime;
}
@Column(name="location_id", nullable=false)
public int getLocationId() {
return this.locationId;
}
public void setLocationId(int locationId) {
this.locationId = locationId;
}
@Column(name="measurement_id", nullable=false)
public int getMeasurementId() {
return this.measurementId;
}
public void setMeasurementId(int measurementId) {
this.measurementId = measurementId;
}
@Column(name="instrument_id", nullable=false)
public int getInstrumentId() {
return this.instrumentId;
}
public void setInstrumentId(int instrumentId) {
this.instrumentId = instrumentId;
}
@Column(name="datetime", nullable=false, length=13)
public Date getDatetime() {
return this.datetime;
}
public void setDatetime(Date datetime) {
this.datetime = datetime;
}
public boolean equals(Object other) {
if ( (this == other ) ) return true;
if ( (other == null ) ) return false;
if ( !(other instanceof TimeseriesId) ) return false;
TimeseriesId castOther = ( TimeseriesId ) other;
return (this.getLocationId()==castOther.getLocationId())
&& (this.getMeasurementId()==castOther.getMeasurementId())
&& (this.getInstrumentId()==castOther.getInstrumentId())
&& ( (this.getDatetime()==castOther.getDatetime()) || ( this.getDatetime()!=null && castOther.getDatetime()!=null && this.getDatetime().equals(castOther.getDatetime()) ) );
}
public int hashCode() {
int result = 17;
result = 37 * result + this.getLocationId();
result = 37 * result + this.getMeasurementId();
result = 37 * result + this.getInstrumentId();
result = 37 * result + ( getDatetime() == null ? 0 : this.getDatetime().hashCode() );
return result;
}
}
I am using annotations since as I am learning hibernate it is easier for me to have both the code and the hibernate annotations before at once instead of moving between the java code and the hibernate.hbm.xml files.
My reading has lead to me suspect that Timeseries.java and TimeseriesId.java are going to be a part of any solution I find, probably with the TimeseriesId being moved inside the Timeseries class which will be renamed TimeseriesElement.java or something similar.
Two strategies for getting the class I want appear to be: 1. Create a Timeseries.java which will contain a map of TimeseriesElement keyed by date; 2. Turn the class Instrument into my
de facto timeseries class. So I will spend some time rereading the hibernate docs to see if I can do either of these or/and if they meet my needs.
we'll see where this takes me.