如何使用 JPA CriteriaBuilder 查询执行外连接?

Dav*_*ave 4 hibernate jpa join outer-join jpa-2.0

我正在使用 JPA 2.0、Hibernate 4.1.0.Final 和 MySQL 5.5.27。我想构造一个 JPA 查询,每行返回两个实体,并且我想执行右外连接。这两个实体是:

\n\n
@Entity\n@Table(name = "user",\n    uniqueConstraints = { @UniqueConstraint(columnNames = { "USER_NAME" }) }\n)\npublic class User implements Comparable<User>, Serializable\n{\n    ...\n    @Column(name = "first_name")\n    @NotNull\n    /* the first name of the User */\n    private String firstName;\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n
@Entity\n@Table(name="code_user",\n    uniqueConstraints = { \n        @UniqueConstraint(columnNames = { "CODE_ID", "USER_ID" }) }\n)\npublic class CodeUser \n{\n\n    @Id\n    @NotNull\n    @GeneratedValue(generator = "uuid-strategy")\n    @Column(name = "ID")\n    private String id;\n\n    @ManyToOne\n    @JoinColumn(name = "CODE_ID", nullable = false, updatable = true)\n    private Code code;\n\n    @ManyToOne\n    @JoinColumn(name = "USER_ID", nullable = false, updatable = true)\n    private User user;\n
Run Code Online (Sandbox Code Playgroud)\n\n

到目前为止,这是我的 JPA,但问题是正在执行内部联接,并且每行仅返回一个实体(用户对象)...

\n\n
    final CriteriaBuilder builder = m_entityManager.getCriteriaBuilder();\n    final CriteriaQuery<User> criteria = builder.createQuery(User.class);\n    final Root<User> user = criteria.from(User.class);\n\n    final Root<CodeUser> codeUser = criteria.from(CodeUser.class);\n    final Join<CodeUser, User> joinUser = codeUser.join(CodeUser_.user);\n    criteria.select(joinUser);\n    \xe2\x80\xa6\n    return criteria.where(builder.and(preds.toArray(new Predicate[preds.size()])));\n
Run Code Online (Sandbox Code Playgroud)\n\n

如何执行外部联接以便返回所有用户并返回任何匹配的 CodeUser 记录?无法向我的用户实体添加额外的成员字段。

\n

And*_*i I 5

您必须检查 Hibernate 是否支持 Right Join,因为根据文档,JPA 提供者不需要支持 RIGHT JOIN :

Java Persistence 2.0 中不需要支持右外连接和右外取连接。使用 RIGHT 连接类型的应用程序将不可移植。

所以,所以,如果您发现没有休眠版本这样做,我看到的唯一解决方案是:

解决方案 1.将 LAZY 字段添加到User实体

@OneToMany(mappedBy="TODO", fetch=FetchType.LAZY)
private Collection<CodeUser> codeUsers;
Run Code Online (Sandbox Code Playgroud)

然后使用 LEFT JOIN 从 User 导航到 CodeUsers。

解决方案 2.进行两个不同的查询:第一个查询获取所有用户,第二个查询获取相应的 CodeUsers。