Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA双向1..N关联,避免在子项中查询以设置父项_Java_Spring_Hibernate_Jpa - Fatal编程技术网

Java JPA双向1..N关联,避免在子项中查询以设置父项

Java JPA双向1..N关联,避免在子项中查询以设置父项,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我正在使用SpringDataJPA+Hibernate作为Web应用程序。对于一个特定的域模型a,我们在另一个域B中有一个1对多的关联。这样a将有一个集合getB,B将有一个getA 在查询图形时,我看到hibernate使用的是1+n查询。一个用于获取A图的外部联接查询,然后是用于在每个B中设置A的“n”查询 我这里有什么图案遗漏吗?既然所有的孩子都有相同的父母,那么不可能以某种方式避免这些“n”查询吗 @MappedSuperclass @Data publ

我正在使用SpringDataJPA+Hibernate作为Web应用程序。对于一个特定的域模型a,我们在另一个域B中有一个1对多的关联。这样a将有一个集合getB,B将有一个getA

在查询图形时,我看到hibernate使用的是1+n查询。一个用于获取A图的外部联接查询,然后是用于在每个B中设置A的“n”查询

我这里有什么图案遗漏吗?既然所有的孩子都有相同的父母,那么不可能以某种方式避免这些“n”查询吗





    @MappedSuperclass
    @Data
    public abstract class Batch implements Serializable {

      private static final long serialVersionUID = 1L;

      @OneToOne(fetch = FetchType.EAGER)
      @JoinColumn(name = "batch_id", referencedColumnName = "batch_id")
      protected BatchID batchId;

    }


    /*
    //The parent class in a simplified form
    */
    @Entity
    @Table(name = "DRYRUN")
    @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
    public class DryrunBatch extends Batch {

      /**
       * 
       */
      private static final long serialVersionUID = -1596595930859735318L;
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      @Getter@Setter
      protected Long id;

      public DryrunTNStatus newTNStatus()
      {
        final DryrunTNStatus tn = new DryrunTNStatus();
        tn.setBatch(this);
        getTnStatus().add(tn);
        return tn;
      }

      @OneToMany(fetch = FetchType.LAZY, mappedBy = "batch")
      @Getter@Setter
      private Set tnStatus = new HashSet();
    }


    //The child class in a simplified form

    @Entity
    @Table(name = "DRYRUN_TN_STATUS")
    @Data
    public class DryrunTNStatus implements Serializable{

      /**
       * 
       */
      private static final long serialVersionUID = -4388406636444350023L;

      public DryrunTNStatus(String accountNo, String telNo) {
        super();

        this.accountNo = accountNo;
        this.telNo = telNo;
      }

      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumn(name = "BATCH_ID", referencedColumnName = "BATCH_ID")
      private DryrunBatch batch;

      public DryrunTNStatus()
      {

      }
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      protected Long id;

    }

使用JpaRepository获取对象图的代码。使用SpringJPA支持强制执行外部联接。与Hibernate的@Fetch注释相比,我更喜欢这个



    DryrunBatch drBatch = drBatchRepo.findOne(new Specification() {

          @Override
          public Predicate toPredicate(Root root, CriteriaQuery query,
              CriteriaBuilder cb) {
            query.distinct(true);
            root.fetch("tnStatus", JoinType.LEFT);
            return cb.equal(root.get("batchId").get("id"),
                batch.getId());

          }
        });

最后是来自日志的hibernate查询。我正在运行一个junit,它从DB中获取一个有10个孩子的家长



    //this query can fetch data for the complete graph??
    Hibernate: select distinct dryrunbatc0_.id as id1_6_0_, tnstatus1_.id as id1_9_1_[etc..] from dryrun dryrunbatc0_ left outer join dryrun_tn_status tnstatus1_ on dryrunbatc0_.batch_id=tnstatus1_.batch_id where dryrunbatc0_.batch_id=15

    //and then 10 queries like
    Hibernate: select dryrunbatc0_.id as id1_6_3_, [etc..] from dryrun dryrunbatc0_ left outer join batch_id batchid1_ on dryrunbatc0_.batch_id=batchid1_.batch_id inner join users user2_ on dryrunbatc0_.created_by=user2_.login_id left outer join dryrun_tn_status tnstatus3_ on dryrunbatc0_.batch_id=tnstatus3_.batch_id where dryrunbatc0_.batch_id=?


您遇到了著名的延迟加载的N+1问题。没有JPA标准的方法来解决这个问题,但是,每个JPA提供程序都提供了启用批处理获取的方法,这将一次加载所有惰性引用,而不是在单个SQL查询中加载每个引用

以下是有关如何在中打开它的信息


下面是关于批处理获取工作原理的解释和使用eclipselink的示例。

您是否尝试过FetchMode@HRgiger是的,我也尝试过JOIN和SUBSELECT。没有任何区别。