1

I have the below query, where two tables are joining on non primary column. The table is joining on one common column.

In entity, I have not provided any joining between User and UserDetails, and I don't want to provide either

SELECT * from User user, UserDetails ud
WHERE user.user_key = :pUserKey // passed in parameter
      user.common_key = ud.common_key

User

@Entity
@Table(name = "USER")
@Data
public class User implements java.io.Serializable {

    private static final long serialVersionUID = 1L;
    
    @Id
    @Column(name = "user_key", nullable = false)
    @JsonIgnore
    private Long userKey;
    
    @Column(name = "common_key ", nullable = false)
    @JsonIgnore
    private Long commonKey;
}

UserDetails

@Entity
@Table(name = "USER_DETAILS")
@Data
public class UserDetails implements java.io.Serializable {

    private static final long serialVersionUID = 1L;
    
    @Id
    @Column(name = "user_details_key", nullable = false)
    @JsonIgnore
    private Long userDetailsKey;
    
    @Column(name = "common_key ", nullable = false)
    @JsonIgnore
    private Long commonKey;
}

How to achieve the same query in JPA specification

SSK
  • 3,444
  • 6
  • 32
  • 59

1 Answers1

1

I have got the solution as expected. I have created new root using query.from()

Below is the complete solution

public static Specification<User> userAndDetails(Long userKey) {
        return (Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
        
            Root<UserDetails> userDetailsRoot = query.from(UserDetails.class);

            Predicate userAndDetailsJoin = builder.equal(
                    root.get(User_.commonKey),
                    userDetailsRoot.get(UserDetails_.commonKey));

            Predicate userKeyPredicate = builder.equal(root.get(User_.userKey),
                    userKey);

            return builder.and(userAndDetailsJoin, userKeyPredicate);
        };
    }
SSK
  • 3,444
  • 6
  • 32
  • 59