Specifications and (null) many-to-one relationships

I have an MVC controller that returns a contact list as JSON. On the interface side, I use the jquery datatables plugin. There is a search field on the interface to filter the list of entities.

my objects:

@Entity
public class Contact implements Serializable {

    protected final static Logger   LOGGER              = LoggerFactory.getLogger(Contact.class);

    private static final long       serialVersionUID    = -3691953100225344828L;

    @Id
    @GeneratedValue(generator = "hibernate-uuid")
    @Column(length = 36, unique = true)
    private String                  id;

    @Version
    @JsonIgnore
    private int                     version;

    private String                  firstname;
    private String                  lastname;

    @ManyToOne
    private Company                 company;

    ... GETTER/SETTER ...
}

and

@Entity
public class Company implements Serializable {

    protected final static Logger   LOGGER              = LoggerFactory.getLogger(Company.class);

    private static final long       serialVersionUID    = -7863930456400256944L;

    @Id
    @GeneratedValue(generator = "hibernate-uuid")
    @Column(length = 36, unique = true)
    private String                  id;

    private String                  companyName;
    private String                  companyName1;
    private String                  companyName2;

    ... GETTER/SETTER ...
}

I use server side processing for the search field, and server side I use specifications.

public class ContactSpecifications {

    public static Specification<Contact> contactFirstnameLike(final String needle) {
        return new Specification<Contact>() {

            @Override
            public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.like(cb.lower(root.<String> get(Contact_.firstname)), needle != null ? needle.toLowerCase() : null);
            }
        };
    }

    public static Specification<Contact> contactLastnameLike(final String needle) {
        return new Specification<Contact>() {

            @Override
            public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.like(cb.lower(root.<String> get(Contact_.lastname)), needle != null ? needle.toLowerCase() : null);
            }
        };
    }

    public static Specification<Contact> contactFullnameLike(final String needle) {
        return new Specification<Contact>() {

            @Override
            public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.or(cb.like(cb.lower(root.<String> get(Contact_.lastname)), needle != null ? needle.toLowerCase() : null), cb.like(cb.lower(root.<String> get(Contact_.firstname)), needle != null ? needle.toLowerCase() : null));
            }
        };
    }

    public static Specification<Contact> contactCompanyCompanyNameLike(final String needle) {
        return new Specification<Contact>() {

            @Override
            public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                final Path<Company> company = root.<Company> get(Contact_.company);
                return cb.like(cb.lower(company.<String> get(Company_.companyName)), needle != null ? needle.toLowerCase() : null);
            }
        };
    }
}

My db request

 contactRepository.findAll(specifications, new PageRequest(0,100));

and specifications

 specifications = Specifications.where(ContactSpecifications.contactFullnameLike(needle)).or(ContactSpecifications.contactCompanyCompanyNameLike(needle));

The needle is the search key from the interface and the mask with surrounding% (for example,% asdf%)

My problem is that if the contact does not have a company, the characteristics do not work properly.

For example, I have 3 contacts:

  • Surname: Schmitz, first name: Max, Company: (null)
  • Surname: Schmitz, Name: Moritz, Company: XY
  • Surname: Muster, Name: Max, Company: XY

    • Schmitz , 2, 1 .
    • max , 3, 1
    • null/empty,

- ?

+4
1

;)

sql- . . , / .

, . - , . .

...

.

public static Specification<Contact> contactCompanyCompanyNameLike(final String needle) {
    return new Specification<Contact>() {

        @Override
        public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            final Join<Contact,Company> company = root.join(Contact_.company, JoinType.LEFT);
            return cb.like(cb.lower(company.<String> get(Company_.companyName)), needle != null ? needle.toLowerCase() : null);
        }
    };
}

.

+2

All Articles