2009-07-22 7 views
2

J'ai problème quand voulez lire l'objet avec lequel (variable double) voici mon code:avec select double dans Hibernate

BranchBuilding Tableau:

@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 

Ceci est mon Gestionnaire de Requêtes:

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

c'est un fabricant de 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; 
    } 

je veux charger une entité buildingBranch par sa Coordonnée géographique mais quand je mets la requête il est Retun nulle.

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 

mais quand je l'utilise requête ci-dessous, il est retourné un résultat correct (je Insertsome de branchbuilding par lat = 0 et long = 0 dans ma table)

return queryManager.executeQuery("from BranchBuildingEntity b where b.buildingAdr.blongitude = 0.0 AND b.buildingAdr.blatitude = 0.0"); 

tout organisme sait où est mon problème?

Répondre

3

Comme David M dit, ne le font pas une comparaison directe des doubles. Soit utiliser une représentation différente ou faire une comparaison indirecte:

abs(b.buildingAdr.blongitude - 51.6371154785156) < threshold 

La valeur seuil dicte à quel point deux longitudes doivent être (numériquement) être considéré comme le même. Vous choisissez donc une valeur pour seuil qui vous convient le mieux (par exemple 0,000000001).

+0

Tanx cette solution résout mon problème – Am1rr3zA

3

Presque certainement pas lié à Hibernate mais simplement à la précision d'un double. Il y a déjà de nombreuses questions sur SO à ce sujet, mais vous essayez essentiellement de comparer à 51.6371154785156, par exemple, et le stockage interne de cette valeur peut ne pas être exactement égal à cela. Si vous souhaitez stocker ces coordonnées à une précision fixe, considérez un type de données décimal offrant cette fonctionnalité, qui corrigera également vos problèmes de sélection.

Exemple: When should I use double instead of decimal?

+0

Je ne suis pas sûr que la raison de ce problème était la précision, je l'ai testé en limitant aussi mais j'ai toujours ce problème – Am1rr3zA

+0

Quand vous dites "par un limité", cependant, voulez-vous dire une décimale plus courte? Vous essayez toujours de comparer deux valeurs doubles pour l'égalité, qui est intrinsèquement sujet à ce genre de problème. –