命名实体图子分子

时间:2016-07-21 13:34:00

标签: java jpa-2.1

我是JPA 2.1的新手,并且最近才开始使用命名实体图。对于我的项目,我在JPA 2.1中映射了以下关系:

订单 - > OrderDetail - >产品 - > PRODUCTLINE

问题:

我想指示JPA加入并正确获取所有需要的数据。到目前为止,这对订单 - >完美无瑕。 OrderDetail - >产品但到目前为止我还没有管理过添加子子图以便与ProductLine类一样深。如何制作子图的子图? Ex获取产品的ProductLine?

这是我的实体(省略了getter和setter):

顺序

@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;
}

的OrderDetail

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

产品

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

PRODUCTLINE

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

    @Column
    private String textDescription;

2 个答案:

答案 0 :(得分:14)

简单的答案是你不能这样做,因为在当前的JPA实现中,你最终会做两个单独的查询并且必须处理笛卡尔积。 JPA的某些未来版本可以扩展到包含更多级别的子图,但是现在它不支持。有一个JPA SPEC组可以在JPA的下一个版本上运行。 Feel free to submit your request/suggestion there

StockOverflow中有another reference to the same question

答案 1 :(得分:0)

您可以使用动态实体图创建多级实体图。 我正在使用jpa 2.2和Hibernate 5.3.7,并且能够创建实体 图形和获取数据多达3级。我希望这会为 下一个水平。下面是代码片段。有关更多详细信息和实际代码,您可以签出我的github存储库:https://github.com/vaneetkataria/Jpa-Hibernate/blob/master/jdbcToJpaMigration/src/test/java/com/katariasoft/technologies/jpaHibernate/entity/fetch/entitygraph/dynamic/MultiInstructorsDynamicEntityGrpahTests.java

代码段:

@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()));
                });
        });
    }
相关问题