problema con select doppia in Hibernate
Domanda
Ho problemi quando vogliono leggere oggetto con cui (doppia variabile) questo è il mio codice:
BranchBuilding Tabella:
@Entity
@Table(name = "branchbuilding", uniqueConstraints={@UniqueConstraint(columnNames={"buildingname","branch_fk"})})//uniqueConstraints={@UniqueConstraint(columnNames={"username","buildingname"})}
public class BranchBuildingEntity implements Serializable {
@Id
@GeneratedValue
private int id;
@Column(name = "buildingname", length = 64)
private String buildingName;
@Column(name = "description", columnDefinition = "mediumtext", length = 16777215)
private String description;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "bremainAdr", column = @Column(name = "bremainadr", columnDefinition = "mediumtext", length = 16777215, nullable=true)),
@AttributeOverride(name = "bmainStreet", column = @Column(name = "bmainstreet", length = 64, nullable=true)),
@AttributeOverride(name = "bstate", column = @Column(length = 64, nullable=true)),
@AttributeOverride(name = "bcity", column = @Column(length = 64, nullable=true)),
@AttributeOverride(name = "bcentralBuilding", column = @Column(name = "bcentralbuilding", columnDefinition = "tinyint", nullable=true)),
@AttributeOverride(name = "blongitude", column = @Column(nullable=true)),
@AttributeOverride(name = "blatitude", column = @Column(nullable=true))
})
Address buildingAdr;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "branch_fk", referencedColumnName = "id", nullable = false)
private BranchEntity branch;
@OneToMany(mappedBy = "branchbuilding", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@OnDelete(action=OnDeleteAction.CASCADE)
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private Set<BuildingTelEntity> buildingtel = new HashSet<BuildingTelEntity>();
//some setter and getter
Adrresse Embbedable:
@Embeddable
public class Address implements Serializable {
String bstate;
String bcity;
String bmainStreet;
String bremainAdr;
double blongitude;
double blatitude;
int bcentralBuilding;
//Some getter and Setter
questo è il mio Query Responsabile:
public List<T> executeQuery(String query, Object... values) throws DatabaseException {
logger.info("it's at the first of executeQuery(String query, Object... values)");
List<Object> ret;
Session sess = null;
boolean freed = false;
List<T> result;
try {
sess = HibernateUtil.getSession();
Transaction tx = sess.beginTransaction();
Query q = sess.createQuery(query);
for (int i = 0; i < values.length; i++) {
if (values[i].getClass().getSimpleName().equals("Long")) {
q.setLong(i, (Long) values[i]);
} else if (values[i].getClass().getSimpleName().equals("String")) {
q.setString(i, (String) values[i]);
} else if (values[i].getClass().getSimpleName().equals("Integer")) {
q.setInteger(i, (Integer) values[i]);
} else if (values[i].getClass().getSimpleName().equals("Double")) {
q.setDouble(i, (Double) values[i]);
} else if (values[i].getClass().getSimpleName().equals("Boolean")) {
q.setBoolean(i, (Boolean) values[i]);
} else {
q.setEntity(i, values[i]);
}
}
ret = q.list();
tx.commit();
result = makeClass(ret);
HibernateUtil.freeSession(sess);
freed = true;
} catch (HibernateException e) {
logger.error("Hibernate Exception occurred in executeQuery() Method", e);
e.printStackTrace();
if (!freed && sess != null) {
HibernateUtil.freeSession(sess);
}
throw new DatabaseException("Can not execute query.");
} catch (Exception e) {
logger.fatal("Exception occurred in executeQuery() Method", e);
System.out.println(e.getMessage());
throw new DatabaseException("Can not execute query.");
}
return result;
}
questo è un creatore di classe:
private List<T> makeClass(List<Object> input) {
List<T> ret = new ArrayList<T>();
int size = input.size();
for (int i = 0; i < size; i++) {
T curr = (T) input.get(i);
ret.add(curr);
}
return ret;
}
voglio caricare un'entità buildingBranch da esso è coordinata geografica, ma quando ho impostato Query è Retun nulla.
return queryManager.executeQuery("from BranchBuildingEntity b where b.buildingAdr.blongitude = 51.6371154785156 AND b.buildingAdr.blatitude = 35.658412064282");
or
return queryManager.executeQuery("from BranchBuildingEntity b where b.buildingAdr.blongitude = ? AND b.buildingAdr.blatitude = ?", longit, latid);//longit and latid both are double
, ma quando uso di query Di seguito è restituire un risultato corretto (I Insertsome branchbuilding dal lat = 0 e lunga = 0 nella mia tabella)
return queryManager.executeQuery("from BranchBuildingEntity b where b.buildingAdr.blongitude = 0.0 AND b.buildingAdr.blatitude = 0.0");
qualsiasi organismo sa dove è il mio problema?
Soluzione
Come dice David M, non fanno confronto diretto delle doppie. O utilizzare una diversa rappresentazione o di fare un confronto indiretto:
abs(b.buildingAdr.blongitude - 51.6371154785156) < threshold
Il valore di soglia detta quanto vicino due longitudini devono essere (numericamente) per essere considerata la stessa. Quindi si sceglie un valore per la soglia che funziona meglio per voi (ad esempio 0,000000001).
Altri suggerimenti
Quasi certamente non Hibernate correlato, ma semplicemente verso il basso per la precisione di un doppio. Ci sono numerose domande già il SO su questo argomento, ma essenzialmente si sta tentando di confrontare 51,6371154785156, per esempio, e la memoria interna di questo valore possono non essere esattamente uguale a questo. Se si desidera memorizzare queste coordinate con una precisione fissa, prendere in considerazione un tipo di dati decimale che offre questa capacità, che sarà anche poi risolvere i problemi di selezione.