web-dev-qa-db-fra.com

Requête personnalisée pour extraire des données de plusieurs tables au printemps Data Jpa

Les entités suivent 

Table de produit

@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

Table 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>();

Ces entités génèrent une table nommée 'order_detail_productlist' Et des champs comme suit order_detail_id et productlist_id

J'exécute la requête suivante dans l'éditeur mysql et cela fonctionne 

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="?"

mais quand je lance dans le référentiel Spring avec l'annotation @Query, cela me donne une exception. J'ai essayé de changer le nom de Order_detail en OrderDetail en fonction d'entités mais de la même exception dans les deux cas.

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 ]

ce que je veux. J'essaie de l'utiliser de cette façon.

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

je veux obtenir des données de plusieurs tables, comme des produits qui sont commandés, etc. 

3
naila naseem

Votre requête n'est pas une requête HQL valide, que hiberate comprend. Vous pouvez utiliser une requête SQL native, mais le cas d'utilisation mentionné peut être facilement réalisé avec HQL. Avant cela, utilisons les correspondances d'annotations appropriées pour l'association 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>();

Produit:

@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>();

Et requête: 

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

Here est une ressource conviviale pour les débutants qui commence avec JPA

3
grizzly

La façon dont vous procédez n'est pas possible car vous affectez le jeu de résultats à List<Product> mais la requête comporte des jointures, cela signifie que le résultat de la requête n'est pas un Product entity.

Vous pouvez essayer de faire une requête native. Par exemple:

@PersistenceContext
private EntityManager entityManager;

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