web-dev-qa-db-fra.com

Sous-graphique de graphique d'entité nommée

Je suis nouveau dans JPA 2.1 et n’ai commencé à utiliser que récemment les graphes d’entité nommés. Pour mon projet, je mappe la relation suivante dans JPA 2.1:

Commande -> CommandeDétail -> Produit -> Ligne de produit

La question:

Je souhaite demander à JPA de rejoindre et de récupérer correctement toutes les données nécessaires. Jusqu'à présent, cela fonctionne parfaitement pour Order -> OrderDetail -> Produit mais je n'ai pas réussi jusqu'ici à ajouter un sous-graphe afin d'aller aussi loin que la classe ProductLine. Comment créer un sous-graphe d'un sous-graphe? Ex obtenir la ProductLine du produit?

Voici mes entités (Getters et setters omis):

Ordre

@Entity
@Table(name="ORDERS")
@NamedEntityGraph(
    name = "graph.Order.details",
    attributeNodes = {
        @NamedAttributeNode(value = "details", subgraph = "graph.OrderDetail.product")
    },
    subgraphs = {
        @NamedSubgraph(name = "graph.OrderDetail.product", attributeNodes = @NamedAttributeNode("product"))
    }
)

public class Order implements Serializable{
  @Id
  @Column(name = "orderNumber")
  private Long number;

  @Column(name = "orderDate")
  private Date date;

  @OneToMany(mappedBy = "order")
  private List<OrderDetail> details;
}

Détails de la commande

@Entity
@Table(name = "orderdetails")
public class OrderDetail implements Serializable{

   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "orderNumber")
   @Id
   private Order order;

   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "productCode", nullable = false)
   @Id
   private Product product;

   @Column(name = "orderLineNumber")
   private int lineNumber;

   @Column(name = "quantityOrdered")
   private int quantity;

Produit

@Entity
@Table(name = "products")
class Product {
    @Column(name = "productCode")
    @Id
    private String code;

    @Column(name = "quantityInStock")
    public int quantity;

    @ManyToOne
    @JoinColumn(name = "productLine")
    private ProductLine line;

Gamme de produits

@Entity
@Table(name = "productlines")
public class ProductLine {
    @Id
    @Column(name = "productLine")
    private String line;

    @Column
    private String textDescription;
26
sashok_bg

La réponse simple est que vous ne pouvez pas faire cela car, avec l'implémentation actuelle de JPA, vous finiriez par faire deux requêtes distinctes et devoir traiter avec les produits cartésiens. Certaines versions futures de JPA pourraient être étendues pour inclure davantage de niveaux de sous-graphes, mais ce n’est pas le cas actuellement. Il existe un groupe SPEC JPA qui fonctionne sur la prochaine version de JPA. N'hésitez pas à soumettre votre demande/suggestion là .

Ici sur StockOverflow, il y a une autre référence à la même question .

14
Daniel Wisehart

Vous pouvez créer des graphes d'entités à plusieurs niveaux avec des graphes d'entités dynamiques . J'utilise jpa 2.2 et Hibernate 5.3.7 et je suis capable de créer des graphes d'entité Et de récupérer des données jusqu'à 3 niveaux. J'espère que cela fonctionnera pour Prochain niveau aussi. Ci-dessous l'extrait de code. Pour plus de détails et le code actuel, vous pouvez consulter mon dépôt github: https://github.com/vaneetkataria/Jpa-Hibernate/blob/master/jdbcToJpaMigration/src/test/Java/com/katariasoft/technologies/jpaHibernate/entity /fetch/entitygraph/dynamic/MultiInstructorsDynamicEntityGrpahTests.Java

Extrait de code :

@SuppressWarnings("unchecked")
    @Test
    @Rollback(false)
    public void fetchInstrctrsIdProofVehiclesStudentsTheirInstructorsVehiclesAndTheirDocuments() {
        doInTransaction(() -> {
            EntityGraph<Instructor> instructorGraph = em.createEntityGraph(Instructor.class);
            instructorGraph.addAttributeNodes(Instructor_.idProof, Instructor_.vehicles);
            Subgraph<Student> studentSubgraph = instructorGraph.addSubgraph(Instructor_.STUDENTS);
            studentSubgraph.addAttributeNodes(Student_.instructors);
            Subgraph<Vehicle> vehicleSubgraph = studentSubgraph.addSubgraph(Student_.VEHICLES);
            vehicleSubgraph.addAttributeNodes(Vehicle_.documents);
            TypedQuery<Instructor> query = em.createQuery("select i from Instructor i ", Instructor.class)
                    .setHint(EntityGraphUtils.FETCH_GRAPH, instructorGraph);
            List<Instructor> instructors = query.getResultList();
            if (Objects.nonNull(instructors))
                instructors.forEach(instructor -> {
                    IdProof idProof = instructor.getIdProof();
                    Set<Vehicle> vehicles = instructor.getVehicles();
                    Set<Student> students = instructor.getStudents();
                    System.out.println(instructor);
                    System.out.println(idProof);
                    if (Objects.nonNull(vehicles))
                        vehicles.forEach(v -> System.out.println(v.getVehicleNumber()));
                    if (Objects.nonNull(students))
                        students.forEach(s -> System.out.println(s.getName()));
                });
        });
    }
0
Vaneet Kataria