JPA Criteria似乎忽略了条件的加入

时间:2016-10-18 09:15:21

标签: java hibernate jpa spring-data criteria

我的应用中有用户联系实体,我需要每个用户都可以添加一些关于每个联系人的私人评论,并且该评论必须仅适用于那个用户。所以我创建了新的实体 - PrivateInfo 。这是代码。

用户类:

@Entity
@Table(name = "users")
@XmlAccessorType(XmlAccessType.FIELD)
public class User implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String login;

// other fields
}

联系班级:

@Entity
@Table(name = "contacts")
@XmlAccessorType(XmlAccessType.FIELD)
public class Contact implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;

@OneToMany(fetch = LAZY, cascade = ALL, mappedBy = "contact")
private Set<PrivateInfo> privateInfo;

// etc.
}

PrivateInfo类:

@Entity
@Table(name = "private_info")
@XmlAccessorType(XmlAccessType.FIELD)
public class PrivateInfo implements Serializable {

@EmbeddedId
private PrivateInfoKey pk;
@Column(name = "additional_info")
private String additionalInfo;

@ManyToOne(fetch = FetchType.EAGER)
@MapsId("contactId")
private Contact contact;

}

@Embeddable
public class PrivateInfoKey implements Serializable {

@Column(name = "contact_id")
private Long contactId;
@Column(name = "user_id")
private Long userId;

}

我正在使用带有 JpaSpecificationExecutor 的Spring Data存储库进行查询,所以这是我尝试编写规范以获取特定用户的私人信息的所有联系人。

public static Specification<Contact> withPrivateInfo(final long userId) {
    return new Specification<Contact>() {

        @Override
        public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            Join<Contact, PrivateInfo> joinPrivateInfo = root.join(Contact_.privateInfo, JoinType.LEFT);
            joinPrivateInfo.on(cb.equal(
                  joinPrivateInfo.get(PrivateInfo_.pk).get(PrivateInfoKey_.userId), userId
            ));

            return cb.conjunction();   // translates in sql like '... where 1 = 1'
        }
    };
}

然而,当我打电话

 contactRepository.findAll(withPrivateInfo(1));

我正在接收联系人,并且每个联系人都在privateInfo字段中包含有关此联系人的所有用户信息(不仅仅是id = 1的用户,如预期的那样)。似乎忽略 join on 条件。

有任何建议如何实现我的目标?也许与另一个实体结构。这可能与JPA / Criteria有关吗?

0 个答案:

没有答案