【问题标题】:Enhanced Spring Data Rest delivers empty relations增强的 Spring Data Rest 提供空关系
【发布时间】:2016-10-01 02:32:56
【问题描述】:

在我当前使用 Spring-Boot、-HATEOAS、-Rest-Data 的实现中,我试图节省一些进一步的休息电话并增强我的信用休息资源以提供信用关系(参见下面的帐户为 ManyToOne 和creditBookingClassPayments 作为 OneToMany)。 现在的问题是我无法让它运行。该调用始终传递空关系。我真的很感激这方面的帮助。

这里是环境:

Credit.java

@Entity
@Getter
@Setter
public class Credit {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Setter(NONE)
    @Column(name = "id")
    private Long itemId;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="account_id", nullable = false)
    private Account account;

    @OneToMany(mappedBy = "credit")
    private List<CreditBookingClassPayment> creditBookingClassPayments = new ArrayList<>();

    @NotNull(message="Please enter a valid short name.")
    @Column(length = 10, nullable = false)
    private String shortName;

    @NotNull(message="Please enter a valid name.")
    @Column(nullable = false)
    private String name;

    ...
}

CreditRepositoryCustomImpl.java

使用QueryDsl来增强信用资源的实现

...    
    @Override
    public List<Credit> findDistinctByAccountItemIdNew(Long accountId) {
        QCredit credit = QCredit.credit;
        QAccount account = QAccount.account;
        QCreditBookingClassPayment creditBookingClassPayment = QCreditBookingClassPayment.creditBookingClassPayment;
        QBookingClass bookingClass = QBookingClass.bookingClass;

        BooleanExpression hasAccountItemId = credit.account.itemId.eq(accountId);
        List<Credit> credits = from(credit).where(hasAccountItemId)
                .innerJoin(credit.account, account)
                .leftJoin(credit.creditBookingClassPayments, creditBookingClassPayment)
                .leftJoin(creditBookingClassPayment.bookingClass, bookingClass).groupBy(credit.itemId).fetch();
        return credits;
    }
...

CreditController.java

在此处查看 responseBody,所有(帐户和信用付款)都可用于信用

@RepositoryRestController
public class CreditController {

    @Autowired
    private CreditRepository creditRepository;

    @RequestMapping(value = "/credit/search/findAllByAccountItemIdNew", method= RequestMethod.GET, produces = MediaTypes.HAL_JSON_VALUE)
    @ResponseBody
    public ResponseEntity<Resources<PersistentEntityResource>> findAllByAccountItemIdNew(@RequestParam Long accountId, PersistentEntityResourceAssembler persistentEntityResourceAssembler) {
        List<Credit> credits = creditRepository.findDistinctByAccountItemIdNew(accountId);
        Resources<PersistentEntityResource> responseBody = new Resources<PersistentEntityResource>(credits.stream()
                .map(persistentEntityResourceAssembler::toResource)
                .collect(Collectors.toList()));
        return ResponseEntity.ok(responseBody);
    }

}

CreditResourceIntegrTest.java

这里 creditResourcesEntity 持有信用但 account 为 null 并且 creditBookingClassPayment 是一个空数组

@Test
public void testFindAllByAccountItemId() throws URISyntaxException {
    URIBuilder builder = new URIBuilder(creditFindAllByAccountItemIdRestUrl);
    builder.addParameter("accountId", String.valueOf(EXPECTED_ACCOUNT_ID));
    builder.addParameter("projection", "base");

    RequestEntity<Void> request = RequestEntity.get(builder.build())
            .accept(MediaTypes.HAL_JSON).acceptCharset(Charset.forName("UTF-8")).build();
    ResponseEntity<Resources<Resource<Credit>>> creditResourcesEntity =
            restTemplate.exchange(request, new ParameterizedTypeReference<Resources<Resource<Credit>>>() {});

    assertEquals(HttpStatus.OK, creditResourcesEntity.getStatusCode());
    //assertEquals(EXPECTED_CREDIT_COUNT, creditResourcesEntity.getBody().getContent().size());
}

我错过了什么吗?

感谢您的帮助! 卡斯滕

【问题讨论】:

    标签: spring rest spring-data-rest querydsl spring-hateoas


    【解决方案1】:

    好的,PersistentEntityResourceAssembler 不支持关系。但这可以通过使用投影来处理。

    CreditProjection.java

    @Projection(name = "base" , types = Credit.class)
    public interface CreditProjection {
    
        String getShortName();
        String getName();
        List<CreditBookingClassPaymentProjection> getCreditBookingClassPayments();
        BigDecimal getValue();
        BigDecimal getInterestRate();
        BigDecimal getMonthlyRate();
    
    }
    

    CreditBookingClassPaymentProjection.java

    @Projection(name = "base" , types = CreditBookingClassPayment.class)
    public interface CreditBookingClassPaymentProjection {
    
        BookingClass getBookingClass();
        CreditPaymentType getCreditPaymentType();
    
    }
    

    CreditController.java

    @RepositoryRestController
    public class CreditController {
    
        @Autowired
        private ProjectionFactory projectionFactory;
    
        @Autowired
        private CreditRepository creditRepository;
    
        @RequestMapping(value = "/credit/search/findAllByAccountItemIdNew", method = RequestMethod.GET, produces = MediaTypes.HAL_JSON_VALUE)
        @ResponseBody
        public ResponseEntity<Resources<?>> findAllByAccountItemIdNew(@RequestParam Long accountId,
                PersistentEntityResourceAssembler persistentEntityResourceAssembler) {
            List<Credit> credits = creditRepository.findDistinctByAccountItemIdNew(accountId);
    
            List<PersistentEntityResource> creditResources = new ArrayList<>();
            for (Credit credit : credits) {
                // credit.getCreditBookingClassPayments()
                PersistentEntityResource creditResource = persistentEntityResourceAssembler.toResource(credit);
                creditResources.add(creditResource);
            }
    
            Resources<CreditProjection> responseBody = new Resources<CreditProjection>(credits.stream()
                    .map(credit -> projectionFactory.createProjection(CreditProjection.class, credit))
                    .collect(Collectors.toList()));
    
            return ResponseEntity.ok(responseBody);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-16
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      • 2014-01-18
      • 2019-07-29
      • 2020-02-17
      • 2019-12-25
      • 1970-01-01
      相关资源
      最近更新 更多