【问题标题】:Hibernate generating a query from Named Query that joins on the wrong column?Hibernate 从连接错误列的命名查询生成查询?
【发布时间】:2013-08-11 01:28:27
【问题描述】:

我正在使用命名查询(hibernate 4)。实体定义如下。

    @Entity
       @NamedQuery(
        name = "findAllProduct",
        query = "SELECT PC.pincode,PO.description"
        +" FROM PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION PVPOL" 
        +" INNER JOIN PVPOL.paymentId PID" 
        +" INNER JOIN PVPOL.pincode PC"
        +" INNER JOIN PVPOL.paymentOptions PO"
        +" where PVPOL.id = :id"

        )


    public class PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION extends baseEntity.Entity {

        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private int id;

        @Column(name="Payment_Id")
        @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="id")
        private Set<Product_Catalog_Vendor> paymentId; 

        @Column(name="pincode_id")
        @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="pincode_id")
        private Set<Pincodes> pincode;      

        @Column(name = "payment_options")

        @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="paymentOptions") 
        private Set<Payment_Options> paymentOptions;

//Protected setter getter here

}

Hibernate 生成下面的 sql:-

    select  pincode2_.pincode as col_0_0_,    paymentopt3_.Description as col_1_0_ 
from    PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION product_ve0_ 
inner join    Product_Catalog_Vendor paymentid1_ 
        on product_ve0_.id=paymentid1_.Id 
inner join    Pincodes pincode2_ 
        on product_ve0_.id=pincode2_.pincode_id 
inner join    payement_options paymentopt3_ 
        on product_ve0_.id=paymentopt3_.payment_options 
where    product_ve0_.id=?

代替

select pincode2_.pincode as col_0_0_,  paymentopt3_.Description as col_1_0_ 
from PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION product_ve0_
INNER JOIN product_catalog_vendor paymentid1_ 
        ON **product_ve0_.payment_id = paymentid1_.id** 
INNER JOIN PINCODES pincode2_ 
        ON **product_ve0_.pincode_id = pincode2_.pincode_id**
INNER JOIN payement_options paymentopt3_ 
        ON **product_ve0_.payment_options=paymentopt3_.payment_options**
where product_ve0_.id=1;

Product_catalog_vendor 类:

@Entity
    public class Product_Catalog_Vendor extends baseEntity.Entity {

            @Id
            @Column(name="Id")
            private int id ;



//Setters and getters here

}

密码实体:

@Entity
public class Pincodes extends baseEntity.Entity {



    @Id
    private int pincode_id;

    @Column(name="pincode")
    private int pincode;


//Setters and getters here
}

payment_options 实体如下:

@Entity
@Table(name="payement_options")     
public class Payment_Options extends baseEntity.Entity {

    @Id
    @Column(name="payment_options")
    private int paymentOptions;


//Setter getter

}

我在很多网站上搜索过,但无法找到背后的原因。如果我做错了什么,请给我建议。一些好的参考将不胜感激。谢谢

【问题讨论】:

  • 提供密码、支付和产品目录实体
  • @bellabax 请在已编辑的问题中找到请求的实体类。期待您的解决方案。谢谢
  • 如果我的建议为您指明了正确的方向,请告诉我

标签: java hibernate jpa hibernate-mapping named-query


【解决方案1】:

只是为了纠正您的问题,您的查询加入了 paymentid1_.Id 而不是 paymentid1_.id?还是我错过了预期查询和实际查询之间的差异?

我不是专业人士,但只是猜测我会说您的查询正在加入 Product_Catalog_Vendor 的 id:

@Id
@Column(name="Id")
private int id ;

所以因为这就是为什么它的 Id 而不是 id...

【讨论】:

  • 我在我的问题中添加了 Product_Catalog_Vendor 类。请再次参考我的问题。谢谢
  • 这是我的错误,我编写了一些错误的生成查询,所以我在其中进行了编辑。我的问题是,我想加入 product_ve0_.payment_id = paymentid1_.id 而不是 product_ve0_.id=paymentid1_.Id。 hibernate 在每个不正确的连接中获取我的实体类 ID。
【解决方案2】:

我认为由于单向映射,您根本不需要 mappedBy,或者无论如何,您正在以一种奇怪的方式使用它们。 mappedBy 仅当关联是双向的(不是您的情况)并且应该引用一个字段,该字段的类型与声明 mappedBy 的实体类型相同(而不是您的 String 类型)案例)。
您使用 mappedBy 的方式类似于 referencedColumnName 属性

在你的例子中:

@Entity
public class Product_Catalog_Vendor extends baseEntity.Entity {
  @ManyToOne
  private PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION pvpol;
}

和

public class PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION extends baseEntity.Entity {
  @Column(name="Payment_Id")
  @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="pvpol")
  private Set<Product_Catalog_Vendor> paymentId;
}

【讨论】:

  • 如果我遵循您的建议,那么我必须在名为 pvpol_id 的数据库表 (product_catalog_vendor) 中再创建一列。是吗?
  • 是的。但真正的问题是:您是否需要它,或者没有mappedBy 也可以?我认为你可以在没有 mappedBy 的情况下做同样的工作
  • 我不想在我的表 (product_catalog_vendor) 中添加新列。如何在不使用 mappedBy 的情况下从 PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION 实体中引用表 product_catalog_vendor 的主键。因为 Payment_Id,pincode_id,payment_options 是我的表中的外键,带有复合键(ID,Payment_Id,PINCODE_ID)。我从过去一个半月开始研究休眠,所以可能我错过了一些东西,你能帮我在这里找到解决方案吗?请在这里找到表格stackoverflow.com/questions/18118440/…
  • 如果不将PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION id 放入Product_Catalog_Vendor,如何从PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION 的单行引用多个Product_Catalog_Vendor 行?或者我错过了什么?在 PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION 中使用 @OneToOne 或 @ManyToOne
  • 是的,你是对的,但是在我的 PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION 表中,我创建了复合主键 (ID,Payment_Id, PINCODE_ID),其中我使用 Payment_Id 来引用 Product_Catalog_Vendor 表的主键 ID,同样我正在引用 PINCODES表的主键 PINCODE_ID 和 PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION 表的 PINCODE_ID 键,它也是外键和主键。我想你是在问我这个?我的方向正确吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 2015-07-22
  • 1970-01-01
  • 2012-01-14
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
相关资源
最近更新 更多