4

JPA 2.0、Hibernate 4.1.0.Final、および MySQL 5.5.27 を使用しています。行ごとに 2 つのエンティティを返す JPA クエリを作成し、右外部結合を実行したいと考えています。2 つのエンティティは次のとおりです。

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

@Entity
@Table(name="code_user",
    uniqueConstraints = { 
        @UniqueConstraint(columnNames = { "CODE_ID", "USER_ID" }) }
)
public class CodeUser 
{

    @Id
    @NotNull
    @GeneratedValue(generator = "uuid-strategy")
    @Column(name = "ID")
    private String id;

    @ManyToOne
    @JoinColumn(name = "CODE_ID", nullable = false, updatable = true)
    private Code code;

    @ManyToOne
    @JoinColumn(name = "USER_ID", nullable = false, updatable = true)
    private User user;

ここまでは私の JPA ですが、問題は内部結合が実行されており、行ごとに 1 つのエンティティ (ユーザー オブジェクト) しか返されないことです...

    final CriteriaBuilder builder = m_entityManager.getCriteriaBuilder();
    final CriteriaQuery<User> criteria = builder.createQuery(User.class);
    final Root<User> user = criteria.from(User.class);

    final Root<CodeUser> codeUser = criteria.from(CodeUser.class);
    final Join<CodeUser, User> joinUser = codeUser.join(CodeUser_.user);
    criteria.select(joinUser);
    …
    return criteria.where(builder.and(preds.toArray(new Predicate[preds.size()])));

すべてのユーザーが返され、一致する CodeUser レコードも返されるように外部結合を実行するにはどうすればよいですか? User エンティティにメンバー フィールドを追加することはできません。

4

3 に答える 3

4

ドキュメントによると、JPA プロバイダーは RIGHT JOIN をサポートする必要がないため、Hibernate が Right Join をサポートしているかどうかを確認する必要があります。

Java Persistence 2.0 では、右外部結合と右外部フェッチ結合をサポートする必要はありません。RIGHT 結合タイプを使用するアプリケーションは移植できません。

したがって、休止状態のバージョンがないことがわかった場合、私が見る唯一の解決策は次のとおりです。

解決策 1. LAZY フィールドをUserエンティティに追加するには

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

次に、LEFT JOIN を使用して User から CodeUsers に移動します。

解決策 2. 2 つの異なるクエリを作成します。最初にすべてのユーザーを取得し、2 番目に対応する CodeUsers を取得します。

于 2013-09-18T09:44:34.753 に答える
3

を作成するには、次の操作を実行できますRIGHT JOIN

Join<CodeUser, User> joinUser = rootCodeUser.join(CodeUser_.user, JoinType.RIGHT);
//now you can add your conditions on the CodeUser

また、より多くのエンティティを選択するには、次の操作を試してください。

CriteriaQuery<Object[]> criteria = builder.createQuery( Object[].class );
Root<CodeUser> codeUserRoot = criteria.from( CodeUser.class );
Join<CodeUser, User> joinUser = rootUser.join(CodeUser_.user, JoinType.RIGHT);

criteria.select( builder.array( joinUser, codeUserRoot ) );
//now you can add you conditions

PS: コードで検出された 1 つの問題は、1 つのルートではなく 2 つのルートを使用することです。

于 2013-09-17T09:38:58.427 に答える
-1

CROSS JOINを使う

    final CriteriaBuilder builder = m_entityManager.getCriteriaBuilder();
    final CriteriaQuery<User> criteria = builder.createQuery(User.class);
    final Root<User> user = criteria.from(User.class);

    final Root<CodeUser> codeUser = criteria.from(CodeUser.class);
    criteria.select(codeUser);
    preds.add(builder.equal(codeUser.get("USER_ID"), user.get("ID")))

    …
    return criteria.where(builder.and(preds.toArray(new Predicate[preds.size()])));
于 2019-07-18T03:47:27.443 に答える