我使用hibernate作为JPA的实现,在实验中遇到一些hibernate的问题:
通过关联表Order查询数据,然后修改OrderDeliverInfo中的字段em.createQuery(
    "update OrderDeliverInfo o set o.deliverWay=?1 where o.order.orderid = ?2")
    .setParameter(1, deliverWay)
    .setParameter(2, orderid)
    .executeUpdate();发送的语句如下:    update
        OrderDeliverInfo,  
    set
        deliverWay=? 
    where
        orderid=?错到家了!!!这样的语句在Toplink中是可以成功执行的。
我这样修改语句:em.createQuery(//
    "update OrderDeliverInfo o set o.deliverWay=?1 where o.order=" +
        "(select o1 from Order o1 where o1.orderid = ?2)")
    .setParameter(1, deliverWay)
    .setParameter(2, orderid)
    .executeUpdate();直接报错(等号左右两边的order不相容):
left and right hand sides of a binary logic operator were incompatibile [cn.itcast.bean.book.Order : cn.itcast.bean.book.Order]请问如果通过修改JPQL来发送正确的update语句,不使用这样的方法:Order order = this.find(orderid);
order.getOrderDeliverInfo().setDeliverWay(deliverWay);
hibernate在有联合主键的情况下,统计的语句也需要注意!!
大家还知道hibernate的那些BUG,又如何解决?

解决方案 »

  1.   

    把你的实体类映射发上来看看?我不认为有这个bug
      

  2.   

    没有映射文件,全是JPA的注解,映射是不会错的。/**
     * 配送信息
     */
    @Entity
    public class OrderDeliverInfo {
    private Integer deliverid;
    /* 收货人姓名 */
    private String recipients;
    /* 配送地址 */
    private String address;
    /* 电子邮箱 */
    private String email;
    /* 邮编 */
    private String postalcode;
    /* 座机 */
    private String tel;
    /* 手机 */
    private String mobile;
    /* 性别 */
    private Gender gender = Gender.MAN;
    /* 配送方式 */
    private DeliverWay deliverWay;
    /* 配送时间要求 */
    private String requirement;

    private Order order;

    @OneToOne(mappedBy="orderDeliverInfo", cascade=CascadeType.REFRESH)
    public Order getOrder() {
    return order;
    }
    public void setOrder(Order order) {
    this.order = order;
    }
    @Id @GeneratedValue
    public Integer getDeliverid() {
    return deliverid;
    }
    public void setDeliverid(Integer deliverid) {
    this.deliverid = deliverid;
    }
    @Enumerated(EnumType.STRING) @Column(length=23, nullable=false)
    public DeliverWay getDeliverWay() {
    return deliverWay;
    }
    public void setDeliverWay(DeliverWay deliverWay) {
    this.deliverWay = deliverWay;
    }
    @Column(length=50)
    public String getRequirement() {
    return requirement;
    }
    public void setRequirement(String requirement) {
    this.requirement = requirement;
    }
    @Column(length=10, nullable=false)
    public String getRecipients() {
    return recipients;
    }
    public void setRecipients(String recipients) {
    this.recipients = recipients;
    }
    @Column(length=50, nullable=false)
    public String getAddress() {
    return address;
    }
    public void setAddress(String address) {
    this.address = address;
    }
    @Column(length=40, nullable=false)
    public String getEmail() {
    return email;
    }
    public void setEmail(String email) {
    this.email = email;
    }
    @Column(length=6)
    public String getPostalcode() {
    return postalcode;
    }
    public void setPostalcode(String postalcode) {
    this.postalcode = postalcode;
    }
    @Column(length=18)
    public String getTel() {
    return tel;
    }
    public void setTel(String tel) {
    this.tel = tel;
    }
    @Column(length=11)
    public String getMobile() {
    return mobile;
    }
    public void setMobile(String mobile) {
    this.mobile = mobile;
    }
    @Enumerated(EnumType.STRING) @Column(length=5,nullable=false)
    public Gender getGender() {
    return gender;
    }
    public void setGender(Gender gender) {
    this.gender = gender;
    }
    @Override
    public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result
    + ((deliverid == null) ? 0 : deliverid.hashCode());
    return result;
    }
    @Override
    public boolean equals(Object obj) {
    if (this == obj)
    return true;
    if (obj == null)
    return false;
    if (getClass() != obj.getClass())
    return false;
    final OrderDeliverInfo other = (OrderDeliverInfo) obj;
    if (deliverid == null) {
    if (other.deliverid != null)
    return false;
    } else if (!deliverid.equals(other.deliverid))
    return false;
    return true;
    }

    }/**
     * 订单实体
     */
    @Entity @Table(name="orders")
    public class Order {
    /* 订单号 */
    private String orderid;
    /* 所属用户 */
    private Buyer buyer;
    /* 订单创建时间 */
    private Date createDate = new Date();
    /* 订单状态 */
    private OrderState state;
    /* 商品总金额 */
    private Float productTotalPrice = 0f;
    /* 配送费 */
    private Float deliverFee = 0f;
    /* 订单总金额 */
    private Float totalPrice= 0f;
    /* 应付款(实际需要支付的费用) */
    private Float payablefee = 0f;
    /* 顾客附言 */
    private String note;
    /* 支付方式 */
    private PaymentWay paymentWay;
    /* 支付状态 */
        private Boolean paymentstate = false;
        /* 订单配送信息 */
    private OrderDeliverInfo orderDeliverInfo;
    /* 订单购买者联系信息 */
    private OrderContactInfo orderContactInfo;
    /* 订单项 */
    private Set<OrderItem> items = new HashSet<OrderItem>(); @Id @Column(length=16)
    public String getOrderid() {
    return orderid;
    }
    public void setOrderid(String orderid) {
    this.orderid = orderid;
    }
    @ManyToOne(cascade=CascadeType.REFRESH,optional=false)
    @JoinColumn(name="username")
    public Buyer getBuyer() {
    return buyer;
    }
    public void setBuyer(Buyer buyer) {
    this.buyer = buyer;
    }
    @Temporal(TemporalType.TIMESTAMP) @Column(nullable=false)
    public Date getCreateDate() {
    return createDate;
    }
    public void setCreateDate(Date createDate) {
    this.createDate = createDate;
    }
    @Enumerated(EnumType.STRING) @Column(length=16,nullable=false)
    public OrderState getState() {
    return state;
    }
    public void setState(OrderState state) {
    this.state = state;
    }
    @Column(nullable=false)
    public Float getProductTotalPrice() {
    return productTotalPrice;
    }
    public void setProductTotalPrice(Float productTotalPrice) {
    this.productTotalPrice = productTotalPrice;
    }
    @Column(nullable=false)
    public Float getDeliverFee() {
    return deliverFee;
    }
    public void setDeliverFee(Float deliverFee) {
    this.deliverFee = deliverFee;
    }
    @Column(nullable=false)
    public Float getTotalPrice() {
    return totalPrice;
    }
    public void setTotalPrice(Float totalPrice) {
    this.totalPrice = totalPrice;
    }
    @Column(nullable=false)
    public Float getPayablefee() {
    return payablefee;
    }
    public void setPayablefee(Float payablefee) {
    this.payablefee = payablefee;
    }
    @Column(length=100)
    public String getNote() {
    return note;
    }
    public void setNote(String note) {
    this.note = note;
    }
    @Enumerated(EnumType.STRING) @Column(length=20,nullable=false)
    public PaymentWay getPaymentWay() {
    return paymentWay;
    }
    public void setPaymentWay(PaymentWay paymentWay) {
    this.paymentWay = paymentWay;
    }
    @Column(nullable=false)
    public Boolean getPaymentstate() {
    return paymentstate;
    }
    public void setPaymentstate(Boolean paymentstate) {
    this.paymentstate = paymentstate;
    }
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="deliver_id")
    public OrderDeliverInfo getOrderDeliverInfo() {
    return orderDeliverInfo;
    }
    public void setOrderDeliverInfo(OrderDeliverInfo orderDeliverInfo) {
    this.orderDeliverInfo = orderDeliverInfo;
    }
    @OneToOne(cascade=CascadeType.ALL, optional=false)
    @JoinColumn(name="contact_id")
    public OrderContactInfo getOrderContactInfo() {
    return orderContactInfo;
    }
    public void setOrderContactInfo(OrderContactInfo orderContactInfo) {
    this.orderContactInfo = orderContactInfo;
    }
    @OneToMany(mappedBy="order", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @OrderBy("itemid asc")
    public Set<OrderItem> getItems() {
    return items;
    }
    public void setItems(Set<OrderItem> items) {
    this.items = items;
    }
    /**
     * 添加订单项
     * @param item
     */
    public void addOrderItem(OrderItem item){
    item.setOrder(this);
    this.items.add(item);
    }

    @Override
    public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((orderid == null) ? 0 : orderid.hashCode());
    return result;
    }
    @Override
    public boolean equals(Object obj) {
    if (this == obj)
    return true;
    if (obj == null)
    return false;
    if (getClass() != obj.getClass())
    return false;
    final Order other = (Order) obj;
    if (orderid == null) {
    if (other.orderid != null)
    return false;
    } else if (!orderid.equals(other.orderid))
    return false;
    return true;
    }

    }
      

  3.   

    我认为hibernate对SQL操作是存在的bug的
    有时候甚至连更新语句都不能写
      

  4.   

      
       感觉hibernate确实是有bug的  不过那要研究hibernate的源代码
      

  5.   

    呵呵,貌似没什么人对hibernate了解
      

  6.   

    使用Hibernate DAO的  attachDirty方法时配置文件要特别小心。可能会出一些奇怪的错误。
      

  7.   

    orderid为主键,你见过主键能相同的?
      

  8.   


    em.createQuery(
        "update OrderDeliverInfo o set o.deliverWay=?1 where o.order= ?2")
        .setParameter(1, deliverWay)
        .setParameter(2, order)
        .executeUpdate();条件为对象看看。
      

  9.   

     也没细看你的问题,
     处理这样的问题hibernate还是没问题的。
     可能楼主对hibernate还是在学习阶段,
     不能熟练的应用。
      

  10.   

    呵呵,还真没这样试过,过会有空试下才再来回楼主的帖,重在实践,hibernate也可能会有bug。
      

  11.   

    无语中我的神呐!
    我知道楼主的意思了
    你的意思是要打出的SQL语句是 update OrderDeliverInfo set deliverWay=? where
            orderid=(select id from Order where id=?)
    是不是?
    //
    1,首先你打出来的SQL语句,而不是HQL语句,SQL语句一般不等同于HQL;绝对不要生搬硬套地把HQL语句翻译成 
       SQL。
    (切记!)
    2,请分析你JPA注解,在看你的表结构:
       你的OrderDeliverInfo 表中orderid是一个外键。你要使用此字段作为更新条件你的SQL语句怎么写?
       毋庸质疑,你会这样写:update OrderDeliverInfo set deliverWay=? where orderid=?
    3,关于你HQL语句的解释:
      首先,hibernate的创始人没有傻到这个程度。能让你一眼就能看出来的BUG;开玩笑了
      第二,hibernate一般是通过外键(无论是你建立的,还是意识存在的)去映射一个实体,所有在POJO中,外
      键的字段关联了一个POJO,并让这个POJO和外键相映射,所以o.order.orderid对应的字段就是
      OrderDeliverInfo中的orderid。所以综上所述,是楼主对HQL和SQL语句对应关系 理解错误 造成的。
    最后在强调一次:
    SQL语句一般不等同于HQL;绝对不要生搬硬套地把HQL语句翻译成SQL。(切记!)  
      

  12.   

    你干吗不用hibernate的saveORUpdate方法呢
      

  13.   

    第一:
    update OrderDeliverInfo set deliverWay=? where
            orderid=(select id from Order where id=?)
    是HQL,不是SQL,我不知道HQL中能不用子查询
    第二:
    我提出的BUG是
    update OrderDeliverInfo o set o.deliverWay=?1 where o.order.orderid = ?2
    这条语句在hibernate中不能正确解析,在Toplink是能成功执行的
    第三:
    select OrderDeliverInfo o where o.order.orderid=?
    这样的语句是可以成功执行的,你可以试一下,这条语句的执行说明你说的“o.order.orderid对应的字段就是 OrderDeliverInfo中的orderid”是不正确的。
      

  14.   

    这要的语句应该是没有问题的,我试试,不过这需要获取order实体,不知道能不能只传个id