>source

두 항목을 기반으로 검색을 구현하고 있습니다.

@Entity(name = "user")
public class UserEntity {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(updatable = false, nullable = false)
    private String id;
    @Column(unique = true, nullable = false)
    private String email;
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "foo_id", referencedColumnName = "id")
    private FooEntity foo;
    private UserType type;
}
@Entity(name = "foo")
public class FooEntity {
    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    @Column(updatable = false, nullable = false)
    private String id;
    private String identifier;
}

이제 이메일 주소 또는 해당 관계의 식별자를 기반으로 FooEntity 관계가 존재할 때 사용자를 찾고 싶습니다. 그리고 UserEntity의 열거 형 유형을 기반으로합니다.

다음 쿼리를 시도했습니다.

public static Specification<UserEntity> emailLike(String text) {
     return (root, query, criteriaBuilder) -> criteriaBuilder.like(root.get("email"), "%" + text + "%");
    }
    
public static Specification<UserEntity> patientIdentifier(String text) {
      return (root, query, criteriaBuilder) -> criteriaBuilder.like(root.join("foo").get("identifier"), "%" + text + "%");
    }
public static Specification<UserEntity> userType(UserType type) {
            return (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("type"), type);
        }
    
final Specification<UserEntity> specification = Specification.where(
                UserSpecification.patientIdentifier(text)
                        .or(UserSpecification.emailLike(text))
        ).and(
                UserSpecification.userType(type)
        );
    
final Page<UserEntity> userEntities = userRepository.findAll(specification, pageable);

이제이 쿼리는 FooEntity와의 관계가 존재할 때 작동하는 것 같습니다. 이 관계가 null이면 이메일과 유형이 일치하더라도 아무 것도 반환되지 않습니다.

누군가 나를 도울 수 있습니까?


  • 답변 # 1

    그냥 가입하는 것이 아니라 왼쪽 조인 또는 오른쪽 조인이어야합니다. 조인은 조인 기준과 일치하는 레코드 만 일치하는 내부 조인입니다. SQL에서 null과 같은 것은 항상 false이므로 조인 사이트 중 하나가 null이고 레코드가 결과 집합에 없습니다. 따라서 왼쪽 조인은 모든 왼쪽 사이트 엔터티로 응답하고 오른쪽 사이트가 null이 아닌 경우 존재하는 경우에만 오른쪽 사이트와 일치한다고 말합니다.

    그래서 조인은 root.join("foo", JoinType.LEFT) (검증되지 않은)

  • 이전 c - openssl 라이브러리를 사용하여 수동으로 암호화 키 찾기
  • 다음 SQL Inner는 두 테이블을 조인하고 조건에 따라 두 번째 열에서 부울 값을 추출합니다