使用ManyToMany约束选择

时间:2011-10-24 12:10:41

标签: select jpa playframework

我有两种模式:

class A extends Model {
    public bool active = true;

    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(
        name = "a_with_b",
        joinColumns = {@JoinColumn (name="a_id")},
        inverseJoinColumns = {@JoinColumn (name="b_id")}
    )
    public List<B> bs;
}

class B extends Model {
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(
        name = "a_with_b",
        joinColumns = {@JoinColumn (name="b_id")},
        inverseJoinColumns = {@JoinColumn (name="a_id")}
    )
    public List<A> as;
}

我试图找到所有定义B的A元素,如下所示:

B b = B.findById(1L);
List<A> as = A.find("active = ? AND b IN ?", false, b); // This doesn't work :/

我该怎么办? 谢谢你的帮助

1 个答案:

答案 0 :(得分:1)

我知道如何执行此操作的唯一方法是定义关系表并使用hql。

你的桌子会是这样的

@Entity
@Table(name = "a")
public class A extends Model {
    @ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinTable(name = "a_with_b",
        joinColumns = @JoinColumn(name = "a_id"),
        inverseJoinColumns = @JoinColumn(name = "b_id")
    )
    private List<B> bs;
}

@Entity
@Table(name = "b")
public class B extends Model {
    @SuppressWarnings("unused")
    @ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    @JoinTable(name = "a_with_b",
        joinColumns = @JoinColumn(name = "b_id"),
        inverseJoinColumns = @JoinColumn(name = "a_id")
    )
    private List<A> as;
}

@Entity
@Table(name = "a_with_b")
public class ABRelation extends GenericModel {
    @EmbeddedId
    private ABRelationPk pk = new ABRelationPk();

    @SuppressWarnings("unused")
    @Column(name="a_id", nullable=false, updatable=false, insertable=false)
    private Long a_id;

    @SuppressWarnings("unused")
    @Column(name="b_id", nullable=false, updatable=false, insertable=false)
    private Long b_id;

    public void setA(A a) {
        pk.setA(a);
    }
    public A getA() {
        return pk.getA();
    }
    public void setB(B b) {
        pk.setB(b);
    }
    public B getB() {
        return pk.getB();
    }
}

@Embeddable
public class ABRelationPk implements Serializable {
    @ManyToOne
    private A a;
    @ManyToOne
    private B b;

    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    public boolean equals(Object o) {
        return EqualsBuilder.reflectionEquals(this, o);
    }
    // setters & getters
}

有关详情,请查看以下链接

http://java-aap.blogspot.com/2006/04/hibernate-annotations-composite.html

你的hql看起来像这样

List<A> as = A.find("SELECT ab.pk.a FROM ABRelation ab WHERE ab.pk.b.id = ? AND ab.pk.a.active = ?", 1L, false).fetch();

但在写完所有内容后,我认为你可以使用当前结构加入。

B b = B.findById(1L);
List<A> as = A.find("SELECT a FROM A a JOIN a.bs b WHERE b = ? AND a.active = ?", b, false).fetch();