I have an entity with a List<>
field in it.
I'm trying to search entries in the database by a search string.
Almost everything works fine, except the case when my entity's hardwareCharacteristicValueList
field is null
.
When it happens the query doesn't return anything, even if I pass to specification a string with existing vendor, model, etc.
What am I doing wrong?
If I comment the line
cb.like(cb.lower(root.join(Hardware_.hardwareCharacteristicValueList).get(HardwareCharacteristicValue_.value)), "%" + search.toLowerCase() + "%")
everything works just fine.
Entity:
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;
}
Specification:
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() + "%"));