web-dev-qa-db-ja.com

Spring Data Jpaで複数のテーブルからデータをフェッチするためのカスタムクエリ

エンティティは次のとおりです

製品テーブル

@Entity
public class Product implements Serializable {
/*@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;*/

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

    @NotNull(message = "Product name must not be null")
    @NotEmpty
    private String name;


    @ManyToOne
    @JoinColumn(name="category_id")
    private Category category;

    @ManyToMany(mappedBy = "productlist")
    private List<OrderDetail> orderDetail =new ArrayList<OrderDetail>();

//getters setter

OrderDetailテーブル

@Entity
public class OrderDetail {

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


     @ManyToOne
     @JoinColumn(name="purchased_By")
     private user PurchasedBy;


    @ManyToMany
     private Set<Product> productlist = new HashSet<Product>();

「order_detail_productlist」という名前のテーブルを生成するこれらのエンティティと、order_detail_idおよびproductlist_idに続くフィールド

私はmysqlエディタで次のクエリを実行していますが、それは機能しています

select u.id, r.name from order_detail u inner join order_detail_productlist ur on(u.id=ur.order_detail_id) inner join product r on(ur.productlist_id=r.id) where u.id="?"

しかし、@ Queryアノテーションを使用してSpringリポジトリで実行すると、例外が発生します。エンティティに従ってOrder_detailの名前をOrderDetailに変更しようとしましたが、どちらの場合も同じ例外です。

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [select r.name from com.example.Domain.OrderDetail u inner join order_detail_productlist ur on(u.id=ur.order_detail_id) inner join Product r on(ur.productlist_id=r.id) where u.id= :id ]

私が欲しいもの。私はこのように使用しようとしています。

public final static String product_ordered ="select r.name from OrderDetail u inner join order_detail_productlist ur " +
            "on(u.id=ur.order_detail_id) inner join Product r" +
            " on(ur.productlist_id=r.id)" +
            " where u.id= :id ";

@Query(product_ordered)
public List<Product> findById(@Param("id") int id);

注文商品など、複数のテーブルからデータを取得したい。

5
naila naseem

クエリは、休止状態が理解できる有効なHQLクエリではありません。ネイティブSQLクエリを使用できますが、前述のユースケースはHQLで簡単に実現できます。その前に、ManytoMany関連付けに適切なアノテーションマッピングを使用してみましょう。

@Entity
@Table(name = "order_detail")
public class OrderDetail {

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


     @ManyToOne
     @JoinColumn(name="purchased_By")
     private user PurchasedBy;


     @ManyToMany
     @JoinTable(
       name="order_detail_productlist",
       joinColumns=@JoinColumn(name="order_detail_id", referencedColumnName="id"),
       inverseJoinColumns=@JoinColumn(name="productlist_id", referencedColumnName="id"))
      private Set<Product> productlist = new HashSet<Product>();

製品:

@Entity
@Table(name ="product")
public class Product implements Serializable {

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

      @NotNull(message = "Product name must not be null")
      @NotEmpty
      @Column(name = "name", nullable = false)
      private String name;


      @ManyToOne
      @JoinColumn(name="category_id")
      private Category category;

      @ManyToMany(mappedBy = "productlist")
      private List<OrderDetail> orderDetail =new ArrayList<OrderDetail>();

そしてクエリ:

public final static String product_ordered ="Select p from Product p Join p.orderDetail od Where od.id = :id";

@Query(product_ordered)
public List<Product> findById(@Param("id") int id);

ここ は、JPAを始めるための初心者フレンドリーなリソースです

6
grizzly

結果セットをList<Product>に割り当てているため、この方法は不可能ですが、クエリにいくつかの結合があります。つまり、クエリの結果はProductエンティティではありません。

ネイティブクエリを試すことができます。例えば:

@PersistenceContext
private EntityManager entityManager;

public List<Object[]> customQuery(int id) {
    Query nativeQuery = entityManager.createNativeQuery(product_ordered).setParameter("id",id);
    return nativeQuery.getResultList();
}
1