代码之家  ›  专栏  ›  技术社区  ›  Am1rr3zA

Hibernate中的select Double出现问题

  •  2
  • Am1rr3zA  · 技术社区  · 17 年前

    我想读取带有where(双变量)的对象时遇到问题

    @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
    

    A应力润滑:

    @Embeddable
    public class Address implements Serializable {
    
        String bstate;
        String bcity;
        String bmainStreet;   
        String bremainAdr;
        double blongitude;
        double blatitude;
        int bcentralBuilding;
    //Some getter and Setter
    

    这是我的查询管理器:

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

    这是一个类生成器:

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

    它是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 
    

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

    有人知道我的问题在哪里吗?

    2 回复  |  直到 17 年前
        1
  •  3
  •   Community Mohan Dere    9 年前

    几乎可以肯定的是,与冬眠无关,只是精确到了一倍。关于这个主题,已经有很多问题了,但本质上你是在尝试与51.6371154785156进行比较,例如,这个值的内部存储可能并不完全等于这个值。如果要将这些坐标存储为固定精度,请考虑一个提供此能力的十进制数据类型,该类型还将修复您的选择问题。

    例子: When should I use double instead of decimal?

        2
  •  3
  •   jon hanson    17 年前

    正如大卫M所说,不要直接比较双打。使用不同的表示法或进行间接比较:

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

    阈值指示两个经度必须(数值上)接近多少才能视为相同。因此,您可以为阈值选择一个最适合您的值(例如0.00000000 1)。