Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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
Spring 用于访问事务外部数据的模式_Spring_Hibernate_Spring Data Jpa_Spring Transactions - Fatal编程技术网

Spring 用于访问事务外部数据的模式

Spring 用于访问事务外部数据的模式,spring,hibernate,spring-data-jpa,spring-transactions,Spring,Hibernate,Spring Data Jpa,Spring Transactions,我有一个SpringBoot应用程序,使用SpringDataJPA,hibernate和MySQL作为数据存储 我的应用程序中有3个层: API服务 应用服务 域服务(带存储库) 应用程序服务的作用是在给定一些业务逻辑的情况下,将支持hibernate的POJO转换为DTO POJO SchoolClass.java @Column Long id; @Column String name; @OneToMany(fetch = FetchType.LAZY, mappedBy = "sc

我有一个SpringBoot应用程序,使用SpringDataJPA,hibernate和MySQL作为数据存储

我的应用程序中有3个层:

  • API服务
  • 应用服务
  • 域服务(带存储库)
  • 应用程序服务的作用是在给定一些业务逻辑的情况下,将支持hibernate的POJO转换为DTO

    POJO

    SchoolClass.java

    @Column
    Long id;
    
    @Column
    String name;
    
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "schoolClass")
    List<Book> books;
    
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "schoolClass")
    List<Student> students;
    
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "schoolClass")
    List<Schedule> schedules;
    
    应用服务

    SchoolClassAppService.java

    @Autowired
    private SchoolClassRepository repository;
    
    @Transactional(readOnly = true)
    public SchoolClass getClassById(Long id) {
      return repository.findById(id);
    }
    
    @Autowired
    private SchoolClassService domainService;
    
    public SchoolClassDto getClassById(Long id) {
      SchoolClass schoolClass = domainService.getClassById(id);
      // convert POJO to DTO;
      return SchoolClassDto;
    }
    
    我的问题是,当我试图在SchoolClassAppService中访问SchoolClass上的子实体时,它们有时是空的。不是所有的,但三个中有两个可以正常工作,但第三个是空的。我试图将子列表标记为急切获取,但显然,在Hibernate开始抛出异常之前,只能急切获取两个集合,而且总是加载所有对象听起来也不是一个好的做法。我没有得到
    LazyInitializationException
    ,只是列表是空的

    在返回getter之前,我尝试在域服务方法中的所有列表上调用getter,以便加载POJO的所有数据,但这似乎不是一个干净的做法


    是否有任何可用的模式可以使事务边界尽可能靠近持久层,同时即使在事务关闭后仍可以处理数据?

    不确定为什么您的集合有时是空的,但可能数据就是这样的

    我就是为这个用例创建的。实际上,您将JPA实体的DTO定义为接口,并将其应用于查询。它支持映射嵌套的DTO、集合等,基本上是您所期望的一切,而且最重要的是,它将提高您的查询性能,因为它将生成只获取DTO实际需要的数据的查询

    您的示例的实体视图可能如下所示

    @EntityView(SchoolClass.class)
    interface SchoolClassDto {
      String getName();
      List<BookDto> getBooks();
    }
    @EntityView(Book.class)
    interface BookDto {
      // Whatever data you need from Book
    }
    
    List<SchoolClassDto> dtos = entityViewManager.applySetting(
      EntityViewSetting.create(SchoolClassDto.class),
      criteriaBuilderFactory.create(em, SchoolClass.class)
    ).getResultList();
    
    @EntityView(SchoolClass.class)
    接口SchoolClassDto{
    字符串getName();
    列出getBooks();
    }
    @EntityView(Book.class)
    接口BookDto{
    //你们需要从书中得到的任何数据
    }
    
    查询可能是这样的

    @EntityView(SchoolClass.class)
    interface SchoolClassDto {
      String getName();
      List<BookDto> getBooks();
    }
    @EntityView(Book.class)
    interface BookDto {
      // Whatever data you need from Book
    }
    
    List<SchoolClassDto> dtos = entityViewManager.applySetting(
      EntityViewSetting.create(SchoolClassDto.class),
      criteriaBuilderFactory.create(em, SchoolClass.class)
    ).getResultList();
    
    List dtos=entityViewManager.applySetting(
    EntityViewSetting.create(SchoolClassDto.class),
    criteriaBuilderFactory.create(em,SchoolClass.class)
    ).getResultList();
    

    请记住,DTO不应该只是复制您的实体,而应该设计为适合您的特定用例。

    您是否在事务中检查了
    SchoolClassRepository
    中的
    SchoolClassRepository
    ?您确定所有这些子项都可以正确地拉入吗?如果您没有接受异常,这可能更多地与未按预期进行保存有关,而不是与加载有关。数据已正确保存。如果我在事务中调用所有子列表的getter,那么一旦事务关闭,数据就存在并且也可用。到目前为止,我能提供的线索是,您不能同时获取两个集合。