我有一个针对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获得的响应,在我的网址: 本地主机/我的应用内/ API /人/
{
"_embedded" : {
"persons" : [ {
"name" : "Jack",
"surname" : "Reds",
"contract" : {
"contractType" : "OTHER",
"contractDesc" : "Other",
...
但是如果我执行这部分代码:
List<Person> persons = personRepository.findAll(new PersonSpec("TEST"));
调试变量&#34;人员&#34;用这些数据定价:
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
&#34;合约类型&#34;和&#34; contractDesc&#34;被设置为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())));
}
出了什么问题?我不明白为什么我的人和我的合同之间没有联系。
感谢。
答案 0 :(得分:1)
这通常是因为LAZY加载 - 当您执行@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
时,它不会处理Contract
数据,因此它会显示为null
。
您可以尝试将fetch = FetchType.LAZY
更改为fetch = FetchType.EAGER
或自行实例化对象。
这里有一些关于LAZY vs EAGER的额外信息:
更新
我知道它已经有一段时间了,但另一种方法是你可以通过对你的服务做一些懒惰的收集:
persons.contracts.size();
确保您的方法包含@Transactional
注释