Hibernate version: 3.2 using Annotations
Mapping documents: Annotated classes, as follows:
Code:
/**
* The class <code>Landmark</code> represents a site
* specific reference name.
*/
@Entity
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = {"col", "row", "label_id" }) })
public class Landmark {
private int id;
private int row;
private int column;
private double distance;
private LandmarkLabel label;
private int landmarkTypeOrdinal;
/**
* Create new landmark label.
*/
public Landmark() {
}
/**
* @return Returns the column.
*/
@Column(name = "col", nullable = false)
public int getColumn() {
return column;
}
/**
* @param column
* The column to set.
*/
public void setColumn(int column) {
this.column = column;
}
/**
* @return Returns the distance.
*/
public double getDistance() {
return distance;
}
/**
* @param distance The distance to set.
*/
public void setDistance(double distance) {
this.distance = distance;
}
/**
* @return Returns the label.
*/
@ManyToOne
public LandmarkLabel getLabel() {
return label;
}
/**
* @param label The label to set.
*/
public void setLabel(LandmarkLabel label) {
this.label = label;
}
/**
* Gets the implementation specific <code>ID</code> for this
* <code>LandmarkLabel</code>.
*
* @return Returns the id.
*/
@Id
@GeneratedValue(strategy = AUTO)
public int getId() {
return id;
}
/**
* Sets the <code>ID</code> for this <code>Landmark</code>.
*
* @param id
* The id to set.
*/
public void setId(int id) {
this.id = id;
}
/**
* @return Returns the landmarkType.
*/
@Transient
public LandmarkType getLandmarkType() {
LandmarkType[] values = LandmarkType.values();
return values[landmarkTypeOrdinal];
}
/**
* @param landmarkType The landmarkType to set.
*/
public void setLandmarkType(LandmarkType landmarkType) {
this.landmarkTypeOrdinal = landmarkType.ordinal();
}
/**
* @return Returns the landmarkTypeOrdinal.
*/
public int getLandmarkTypeOrdinal() {
return landmarkTypeOrdinal;
}
/**
* @param landmarkTypeOrdinal The landmarkTypeOrdinal to set.
*/
public void setLandmarkTypeOrdinal(int landmarkTypeOrdinal) {
this.landmarkTypeOrdinal = landmarkTypeOrdinal;
}
/**
* @return Returns the row.
*/
@Column(nullable = false)
public int getRow() {
return row;
}
/**
* @param row
* The row to set.
*/
public void setRow(int row) {
this.row = row;
}
}
Code:
/**
* The class <code>LandmarkLabel</code> represents
* the distance of a landmark in a particular tube from
* that tube's inlet end.
*/
@Entity
@Table
public class LandmarkLabel {
private int id;
private String label;
/**
* Create new landmark label.
*/
public LandmarkLabel() {
}
/**
* @param label
* label to create
*/
public LandmarkLabel(String label) {
this.label = label;
}
/**
* Gets the implementation specific <code>ID</code> for this
* <code>LandmarkLabel</code>.
*
* @return Returns the id.
*/
@Id
@GeneratedValue(strategy = AUTO)
public int getId() {
return id;
}
/**
* Sets the <code>ID</code> for this <code>Plant</code>.
*
* @param id
* The id to set.
*/
public void setId(int id) {
this.id = id;
}
/**
* @return Returns the label.
*/
@Column(nullable = false, unique = true)
public String getLabel() {
return label;
}
/**
* @param label
* The label to set
*/
public void setLabel(String label) {
this.label = label;
}
/**
* {@inheritDoc}
*/
public String toString() {
return getLabel();
}
}
Name and version of the database you are using: postgresql 8.1.14
The generated SQL (show_sql=true): select
this_.id as id4_1_,
this_.distance as distance4_1_,
this_.landmarkTypeOrdinal as landmark3_4_1_,
this_.label_id as label6_4_1_,
this_.col as col4_1_,
this_.row as row4_1_,
landmarkla2_.id as id5_0_,
landmarkla2_.label as label5_0_
from
Landmark this_
left outer join
LandmarkLabel landmarkla2_
on this_.label_id=landmarkla2_.id
where
(
this_.col=?
and this_.row=?
)
The problem: I am attempting to limit the number of Landmarks returned by using a LandmarkLabel instance, as well as some Landmark data. The following code is based upon the DAO examples, given on the site.
Code:
public Landmark findByRowColumnName(int row, int column, String name) {
LandmarkLabel label = new LandmarkLabel();
label.setLabel(name);
LandmarkLabelDAO llDAO = (LandmarkLabelDAO) this.getDatabaseConnection().getDAO(LandmarkLabel.class);
LandmarkLabel found = llDAO.findByExample(label, new String[0]).get(0);
Landmark example = new Landmark();
example.setRow(row);
example.setColumn(column);
example.setLabel(found);
return findByExample(example, new String[0]).get(0);
}
So, why doesn't the LandmarkLabel object limit the number of values returned? I have set the values for the Landmark to return a unique instance, but instead it is returning every row that contains "row" and "col", which happens to be 20 rows instead of the expected 1.
I have tried to search for the answer, but none of the other many-to-one problems seem to be related to this question (but that could be my naivete).
Thanks.