Java 弹簧数据规格+;JPA标准。如果root.join(ListAttribute)为null,则查询不';行不通

Java 弹簧数据规格+;JPA标准。如果root.join(ListAttribute)为null,则查询不';行不通,java,spring-boot,spring-data-jpa,jpa-criteria,Java,Spring Boot,Spring Data Jpa,Jpa Criteria,我有一个实体,其中有一个列表字段。 我正试图通过搜索字符串搜索数据库中的条目。 除了实体的hardwareCharacteristicValueList字段为null时,几乎所有操作都正常。 发生这种情况时,查询不会返回任何内容,即使我向规范传递了一个包含现有供应商、模型等的字符串 我做错了什么 如果我评论这句话 cb.like(cb.lower(root.join(Hardware_.hardwareCharacteristicValueList).get(HardwareCharacteri

我有一个实体,其中有一个
列表
字段。 我正试图通过搜索字符串搜索数据库中的条目。 除了实体的
hardwareCharacteristicValueList
字段为
null
时,几乎所有操作都正常。 发生这种情况时,查询不会返回任何内容,即使我向规范传递了一个包含现有供应商模型等的字符串

我做错了什么

如果我评论这句话

cb.like(cb.lower(root.join(Hardware_.hardwareCharacteristicValueList).get(HardwareCharacteristicValue_.value)), "%" + search.toLowerCase() + "%")
一切正常

实体:

import lombok.*;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

@Entity
@Table(name = "hardware")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Hardware implements Serializable {

    @Id
    @GenericGenerator(name = "hardware_id_sequence", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
            parameters = {@Parameter(name = "sequence_name", value = "SEQ_HARDWARE")})
    @GeneratedValue(generator = "hardware_id_sequence")
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "vendor")
    private String vendor;

    @Column(name = "model")
    private String model;

    @Column(name = "serial", nullable = false)
    private String serial;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "employee_id")
    private Employee employee;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "state_id")
    private HardwareState state;

    @Column(name = "is_visible",nullable = false)
    private Boolean isVisible;

    @Column(name = "comment")
    private String comment;

    @Column(name = "inspection_date")
    private Long inspectionDate;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "hardware_type_id",nullable = false)
    private HardwareType hardwareType;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "hardware")
    private List<HardwareCharacteristicValue> hardwareCharacteristicValueList;
}
import lombok.*;
导入org.hibernate.annotations.GenericGenerator;
导入org.hibernate.annotations.Parameter;
导入javax.persistence.*;
导入java.io.Serializable;
导入java.util.List;
@实体
@表(name=“硬件”)
@吸气剂
@塞特
@诺尔格构装师
@AllArgsConstructor
@建筑商
公共类硬件实现可序列化{
@身份证
@GenericGenerator(name=“hardware\u id\u sequence”,strategy=“org.hibernate.id.enhanced.SequenceStyleGenerator”,
参数={@Parameter(name=“sequence\u name”,value=“SEQ\u HARDWARE”)}
@GeneratedValue(generator=“硬件\u id\u序列”)
@列(name=“id”,nullable=false)
私人长id;
@列(name=“供应商”)
私人字符串供应商;
@列(name=“model”)
私有字符串模型;
@列(name=“serial”,nullable=false)
私有字符串序列;
@manytone(fetch=FetchType.LAZY)
@JoinColumn(name=“employee\u id”)
私人雇员;
@manytone(fetch=FetchType.LAZY)
@JoinColumn(name=“state\u id”)
私有硬件产业国家;
@列(name=“is_visible”,nullable=false)
私有布尔值是可见的;
@列(name=“comment”)
私有字符串注释;
@列(名称=“检验日期”)
私人长期检查日期;
@manytone(fetch=FetchType.LAZY)
@JoinColumn(name=“hardware\u type\u id”,nullable=false)
私有硬件类型硬件类型;
@OneToMany(fetch=FetchType.LAZY,mappedBy=“硬件”)
私有列表硬件特性值列表;
}
规格:

public static Specification<Hardware> searchSubstring(String search) {
        return (root, criteriaQuery, cb) -> cb.or(cb.like(cb.lower(root.get(Hardware_.model)), "%" + search.toLowerCase() + "%"),
                                                    cb.like(cb.lower(root.get(Hardware_.vendor)), "%" + search.toLowerCase() + "%"),
                                                    cb.like(cb.lower(root.get(Hardware_.serial)), "%" + search.toLowerCase() + "%"),
                                                    cb.like(cb.lower(root.get(Hardware_.hardwareType).get(HardwareType_.name)), "%" + search.toLowerCase() + "%"),
                                                    cb.like(cb.lower(root.get(Hardware_.employee).get(Employee_.lastName)), "%" + search.toLowerCase() + "%"),
                                                    cb.like(cb.lower(root.join(Hardware_.hardwareCharacteristicValueList).get(HardwareCharacteristicValue_.value)), "%" + search.toLowerCase() + "%"),
                                                    cb.like(cb.lower(root.get(Hardware_.state).get(HardwareState_.name)), "%" + search.toLowerCase() + "%"));
公共静态规范搜索子字符串(字符串搜索){
return(root,criteriaQuery,cb)->cb.or(cb.like(cb.lower(root.get(Hardware.model)),“%”“+”search.toLowerCase()+“%”,
cb.like(cb.lower(root.get(Hardware.vendor)),“%”加上search.toLowerCase()+“%”,
cb.like(cb.lower(root.get(Hardware_u.serial)),“%”+search.toLowerCase()+“%”,
cb.like(cb.lower(root.get(Hardware.hardwareType).get(hardwareType.name)),“%”“+”search.toLowerCase()+“%”,
cb.like(cb.lower(root.get(Hardware.employee).get(employee.lastName)),“%”“+”search.toLowerCase()+“%”,
cb.like(cb.lower(root.join(Hardware\uwareCharacteristicValueList).get(HardwareCharacteristicValue\uwareCharacteristicValue)),“%”“%”+search.toLowerCase()+“%”,
cb.like(cb.lower(root.get(Hardware.state).get(HardwareState.name)),“%”“+”search.toLowerCase()+“%”);
解决方案:

public static Specification<Hardware> searchSubstring(String search) {
    return (root, criteriaQuery, cb) -> cb.or(cb.like(cb.lower(root.get(Hardware_.model)), "%" + search.toLowerCase() + "%"),
                                                cb.like(cb.lower(root.get(Hardware_.vendor)), "%" + search.toLowerCase() + "%"),
                                                cb.like(cb.lower(root.get(Hardware_.serial)), "%" + search.toLowerCase() + "%"),
                                                cb.like(cb.lower(root.join(Hardware_.hardwareType, JoinType.LEFT).get(HardwareType_.name)), "%" + search.toLowerCase() + "%"),
                                                cb.like(cb.lower(root.join(Hardware_.employee, JoinType.LEFT).get(Employee_.lastName)), "%" + search.toLowerCase() + "%"),
                                                cb.like(cb.lower(root.join(Hardware_.hardwareCharacteristicValueList, JoinType.LEFT).get(HardwareCharacteristicValue_.value)), "%" + search.toLowerCase() + "%"),
                                                cb.like(cb.lower(root.join(Hardware_.state, JoinType.LEFT).get(HardwareState_.name)), "%" + search.toLowerCase() + "%"));
公共静态规范搜索子字符串(字符串搜索){
return(root,criteriaQuery,cb)->cb.or(cb.like(cb.lower(root.get(Hardware.model)),“%”“+”search.toLowerCase()+“%”,
cb.like(cb.lower(root.get(Hardware.vendor)),“%”加上search.toLowerCase()+“%”,
cb.like(cb.lower(root.get(Hardware_u.serial)),“%”+search.toLowerCase()+“%”,
cb.like(cb.lower(root.join(Hardware.hardwareType,JoinType.LEFT).get(hardwareType.name)),“%”“%”+search.toLowerCase()+“%”,
cb.like(cb.lower(root.join(Hardware.employee,JoinType.LEFT).get(employee.lastName)),“%”“+”search.toLowerCase()+“%”,
cb.like(cb.lower(root.join(Hardware.hardwareCharacteristicValueList,JoinType.LEFT).get(hardwareCharacteristicValues(HardwareCharacteristicValue)),“%”加上search.toLowerCase()+“%”,
like(cb.lower(root.join(Hardware.state,JoinType.LEFT).get(HardwareState.name)),“%”“+”search.toLowerCase()+“%”);

我认为您必须指定JoinType。您可以这样尝试吗?root.join(硬件特性值列表,JoinType.LEFT)。get(硬件特性值)@nikolay