0

Oracleには と という2つのテーブルがproductありますproduct_image。名前が示すように、1 対多の関係がありますproductproduct_image.

productエンティティ:

@Entity
@Table(name = "PRODUCT", catalog = "", schema = "WAGAFASHIONDB")
public class Product  implements java.io.Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "PROD_ID", nullable = false, precision = 35, scale = 0)
    @SequenceGenerator(name = "productIdSequence", sequenceName = "PRODUCT_SEQ", allocationSize=1, initialValue=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "productIdSequence")
    private Long prodId;
    @Column(name = "PROD_NAME", length = 50)
    private String prodName;
    @Column(name = "PROD_CODE", length = 50)
    private String prodCode;
    @Lob
    @Column(name = "PROD_DESC")
    private String prodDesc;
    @Basic(optional = false)
    @Column(name = "MARKET_PRICE", nullable = true, precision = 35, scale = 2)
    private BigDecimal marketPrice;
    @Basic(optional = false)
    @Column(name = "SALE_PRICE", nullable = true, precision = 35, scale = 2)
    private BigDecimal salePrice;
    @Column(name = "PROD_FEATURED")
    private Short prodFeatured;
    @Column(name = "EXPRESS_DELIVERY")
    private Short expressDelivery;
    @Basic(optional = false)
    @Column(name = "PROD_WEIGHT", nullable = true, precision = 35, scale = 2)
    private BigDecimal prodWeight;
    @Column(name = "PROD_OCCASSION", length = 50)
    private String prodOccassion;
    @Basic(optional = false)
    @Column(name = "QTY_AVAILABLE", nullable = true)
    private BigInteger qtyAvailable;
    @Column(name = "LATEST")
    private Short latest;
    @Column(name = "VISIBLE")
    private Short visible;
    @JoinTable(name = "PRODUCT_SIZE", joinColumns = {
        @JoinColumn(name = "PROD_ID", referencedColumnName = "PROD_ID")}, inverseJoinColumns = {
        @JoinColumn(name = "SIZE_ID", referencedColumnName = "SIZE_ID")})
    @ManyToMany(fetch = FetchType.LAZY)
    private Set<SizeTable> sizeTableSet;
    @ManyToMany(mappedBy = "productSet", fetch = FetchType.LAZY)
    private Set<Colour> colourSet;
    @OneToMany(mappedBy = "prodId", fetch = FetchType.LAZY)
    private Set<Measurement> measurementSet;
    @OneToMany(mappedBy = "prodId", fetch = FetchType.LAZY)
    private Set<Wish> wishSet;
    @OneToMany(mappedBy = "prodId", fetch = FetchType.LAZY)
    private Set<Cart> cartSet;



    @OneToMany(mappedBy = "prodId", fetch = FetchType.LAZY)
    private Set<ProductImage> productImageSet;             //<--------



    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product", fetch = FetchType.LAZY)
    private Set<OrderItem> orderItemSet;
    @JoinColumn(name = "SUB_CAT_ID", referencedColumnName = "SUB_CAT_ID")
    @ManyToOne(fetch = FetchType.LAZY)
    private Subcategory subCatId;
    @JoinColumn(name = "FABRIC_ID", referencedColumnName = "FABRIC_ID", nullable = false)
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Fabric fabricId;
    @JoinColumn(name = "BRAND_ID", referencedColumnName = "BRAND_ID")
    @ManyToOne(fetch = FetchType.LAZY)
    private Brand brandId;
    @OneToMany(mappedBy = "prodId", fetch = FetchType.LAZY)
    private Set<Inquiry> inquirySet;
    @OneToMany(mappedBy = "prodId", fetch = FetchType.LAZY)
    private Set<Rating> ratingSet;
}

ProductImageエンティティ:

@Entity
@Table(name = "PRODUCT_IMAGE", catalog = "", schema = "WAGAFASHIONDB")
public class ProductImage  implements java.io.Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "PROD_IMAGE_ID", nullable = false, precision = 35, scale = 0)
    @SequenceGenerator(name = "productIdSequence", sequenceName = "PRODUCT_IMAGE_SEQ", allocationSize=1, initialValue=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "productIdSequence")
    private Long prodImageId;
    @Lob
    @Column(name = "PROD_IMAGE")
    private String prodImage;
    @JoinColumn(name = "PROD_ID", referencedColumnName = "PROD_ID")



    @ManyToOne(fetch = FetchType.LAZY)
    private Product prodId;           //<--------------
}

prodId行の各グループ (実際には製品の各グループ)の最大の行のみをフェッチする必要がありますProductImage。つまり、グループごとに最大の N です。

Oracle ネイティブ SQL は、次のように構築できます。

SELECT pi.prod_image_id, pi.prod_id, pi.prod_image 
FROM product_image pi 
INNER JOIN (select max(pi.prod_image_id) AS prod_image_id, pi.prod_id FROM product_image pi GROUP BY pi.prod_id) prod_image 
ON pi.prod_image_id=prod_image.prod_image_id

これは意図したとおりに機能しますが、この SQL を HQL に変換できませんでした。createQuery()メソッドで HQL として直接実行しようとするとQuerySyntexException、最初の開き括弧で予期しないトークンが発生します。この SQL を HQL に変換するヒントを教えてください。


編集:

次のようないくつかの質問は、実際にはこれを達成するためにまだ答えられていません。

HQL を介して Hibernate でこれを達成する方法はないと思います。いくつかの DTO クラスを使用して、この SQL を適切な 2 つ以上の HQL ステートメントに分割する必要がある場合があります。上記の SQL のような単一の HQL ステートメントで可能であれば、ここでの回答を忘れないでください。アプリケーションの多くの場所でそのような要件があるためです。

4

1 に答える 1

1

これを見てください:

select 
    pi.prodImageId, 
    pi.prodId 
from 
    ProductImage pi 
where 
    pi.prodImageId in (
    select max(pis.prodImageId)
    from Product p
        inner join p.productImageSet pis
    group by p.prodId
)

これは次のように変換されます。

select
   productima0_.prodImageId as col_0_0_,
   productima0_.prodId_prodId as col_1_0_,
   product1_.prodId as prodId18_,
   product1_.name as name18_ 
from
   ProductImage productima0_ 
inner join
   Product product1_ on productima0_.prodId_prodId=product1_.prodId 
where
   productima0_.prodImageId in (
      select max(productima3_.prodImageId) 
      from 
         Product product2_ inner join ProductImage productima3_ on product2_.prodId=productima3_.prodId_prodId 
      group by product2_.prodId
   )

あなたが欲しいものはどれですか?

于 2013-04-06T19:46:23.887 に答える