涉及 M2M 关系的 Ebean AND 查询

Ebean AND query involving M2M relationship

我对使用 PlayFramework 2.2.3 的多对多关系的 AND 查询有疑问。我有 class 具有用户参与的线程列表的用户和 class 具有特定线程中涉及的用户列表的 MessageThread。

我的用户class:

@Entity
@Table(name="User")
public class User extends Model {

@Id
public String email;
.
.
.
@ManyToMany(cascade = CascadeType.ALL)
public List<MessageThread> threads = new ArrayList<MessageThread>();

和class MessageThread:

@Entity
public class MessageThread extends Model {

@Id
public Long id;
@ManyToMany(mappedBy="threads")
public List<User> users = new ArrayList<User>();
@OneToMany
public List<Message> messages = new ArrayList<Message>();
@Formats.DateTime(pattern="dd/MM/yyyy")
public Date date = new Date();

public MessageThread(User u1, User u2) {
    this.users.add(u1);
    this.users.add(u2);
}

public static MessageThread create(User u1, User u2) {
    MessageThread mt = new MessageThread(u1, u2);
    mt.save();
    mt.saveManyToManyAssociations("users");
    mt.update();
    u1.threads.add(mt);
    u1.update();
    u2.threads.add(mt);
    u2.update();
    return mt;
}


public static Model.Finder<String, MessageThread> find = new Model.Finder<String, MessageThread>(
        String.class, MessageThread.class);

public static List<MessageThread> findInvolving(String user1, String user2) {
    return find.where().and(com.avaje.ebean.Expr.eq("users.email", user1),com.avaje.ebean.Expr.eq("users.email", user2))
        .findList();
}

public boolean addMessage(Message m) {
    this.messages.add(m);
    return true;
}

}

我的数据库查询不正确吗?

public static List<MessageThread> findInvolving(String user1, String user2) {
    return find.where().and(com.avaje.ebean.Expr.eq("users.email", user1),com.avaje.ebean.Expr.eq("users.email", user2))
        .findList();
}

谢谢

编辑:我做了一些更多的测试,看起来我对数据库的查询是错误的,因为当我只做 where().eq("users.email", user1)where().eq("users.email", user2) 它总是 returns 我相同的列表(因为我现在只有一个实体)但是当使用 AND 查询时它总是返回空列表

编辑:

这是一种基于建议的原始 SQL 查询为我工作的班轮。基本上在 Ebean 中也有 in() method/call (我不知道我应该使用 in 而不是 and)

 find.where().in("users", new Object[]{user1, user2}).findUnique();

您可以使用接受的答案中提出的原始 SQL 查询或 Ebean 中的 in() 方法。

我通过创建自定义 SQL 查询找到了解决方案(类似的方法可能也适用于您的情况):

SELECT * FROM gom_conversation c INNER JOIN gom_user_gom_conversation u ON c.id = u.gom_conversation_id WHERE u.gom_user_id IN ('516645a0-7fc4-494f-9c96-8d83076ba17b', '6b37b10b-fcd1-48da-b635-b973105fa3b1') HAVING COUNT(DISTINCT u.gom_user_id) = 2;

这基本上将结果限制为包含两个匹配项的结果。

以及生成的 ebean 查询:

String sql = "SELECT id FROM gom_conversation c INNER JOIN gom_user_gom_conversation u " +
            "ON c.id = u.gom_conversation_id " +
            "WHERE " +
            "u.gom_user_id IN (:user, :recipient) HAVING COUNT(DISTINCT u.gom_user_id) = 2;";


RawSql rawSql = RawSqlBuilder.parse(sql)
            .tableAliasMapping("id", "id")
            .create();

ConversationModel conversation = find.setRawSql(rawSql)
            .setRawSql(rawSql)
            .setParameter("user", user.id)
            .setParameter("recipient", recipient.id)
            .findUnique();

return conversation;

希望对你的情况有所帮助。