Question

I have problem when want read object with where (double variable) this is my Code :

BranchBuilding Table:

@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

this is my Query Manager:

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

this is a class maker:

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

i want load a buildingBranch entity by it's Geographical coordinate but when I set Query it's retun null.

 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 

but when I use Query Below it's return a correct result(I Insertsome branchbuilding by lat = 0 and long = 0 in my table)

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

any body know where is my Problem?

Was it helpful?

Solution

As David M says, don't do direct comparison of doubles. Either use a different representation or do an indirect comparison :

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

The threshold value dictates how close two longitudes have to be (numerically) to be considered to be the same. So you pick a value for threshold that works best for you (e.g. 0.000000001).

OTHER TIPS

Almost certainly not Hibernate related but simply down to the precision of a double. There are numerous questions already on SO about this topic, but essentially you are trying to compare to 51.6371154785156, for example, and the internal storage of this value may not be exactly equal to this. If you want to store these coordinates to a fixed precision, consider a decimal data type which offers this capability, which will also then fix your select problems.

Example: When should I use double instead of decimal?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top