我有一个针对Person类和Contract类的Spring Data REST实现。

这是我的Person.class:

@Entity
@Table
public class Person {

    @Column
    private String name;

    @Column
    private String surname;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Contract> contracts;

}


这是我的Contract.class:

@Entity
@Table
public class Contract {

    @Column
    private String contractType;

    @Column
    private String contractDesc;

}


这些是我的表定义和数据(在嵌入式HSQL数据库中自动生成的脚本):

CREATE MEMORY TABLE PUBLIC.PERSON(ID, NAME, SURNAME, CONTRACT_ID);
CREATE MEMORY TABLE PUBLIC.CONTRACT(ID, CONTRACTTYPE, CONTRACTDESC);
ALTER TABLE PUBLIC.PERSON ADD CONSTRAINT FK_ABCDEFGHIJKLMNOPQRSTUVWXY FOREIGN KEY(CONTRACT_ID) REFERENCES PUBLIC.CONTRACT(ID);
INSERT INTO PERSON VALUES('9876543210abcdefghijklmnopqrstuv', 'Jack', 'Reds','1234567890abcdefghijklmnopqrstuv');
INSERT INTO CONTRACT VALUES('1234567890abcdefghijklmnopqrstuv', 'OTHER', 'Other');


这是从Spring Data REST获得的响应,位于我的URL:
本地主机/ my-app / api / persons /

{
  "_embedded" : {
    "persons" : [ {
      "name" : "Jack",
      "surname" : "Reds",
      "contract" : {
        "contractType" : "OTHER",
        "contractDesc" : "Other",
    ...


但是,如果我执行这部分代码:

List<Person> persons = personRepository.findAll(new PersonSpec("TEST"));


在调试中,变量“ persons”将与以下数据相称:

persons= ArrayList<E> (id=233)
    elementData=Object[7] (id=235)
        [0]= Person (id=236)
            name= "Jack" (id=176)
            surname= "Reds" (id=180)
            contract= Contract_$$_jvst951_d (id=240)
                contractType= null
                contractDesc= null
        [1]= Person (id=237)
        [2]= Person (id=238)
    modCount=1
    size = 3


“ contractType”和“ contractDesc”设置为NULL。
此外,我的PersonSpec似乎不对这些字段进行任何过滤:

public class PersonSpec implements Specification<Person> {

    @Override
    public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

            if (StringUtils.isNotBlank(searchParam.getContract())) {
                predicates.add(cb.and(cb.and(cb.isNotNull(root.get("contract")),
                                             cb.isNotNull(root.get("contract").get("contractType"))),
                                       cb.equal(root.get("contract").get("contractType"), searchParam.getContract())));
            }


怎么了?我不明白为什么我的人与我的合同之间没有联系。

谢谢。

最佳答案

这通常是由于LAZY加载导致的-当您执行@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)时,它并不会带来Contract数据,因此为什么将其显示为null

您可以尝试通过将fetch = FetchType.LAZY更改为fetch = FetchType.EAGER或自己实例化该对象。

以下是LAZY与EAGER的一些额外信息:


Difference between FetchType LAZY and EAGER in Java persistence?
Hibernate Eager vs Lazy Fetch Type


更新
我知道已经有一段时间了,但是您可以通过对服务执行以下操作来获取惰性集合:

persons.contracts.size();


只要确保您的方法包含@Transactional批注

关于java - Spring Data REST:NULL值问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36285073/

10-14 08:06