Ebean和涉及M2M关系的查询

时间:2015-03-17 16:59:03

标签: java playframework playframework-2.0 ebean

我在使用PlayFramework 2.2.3时遇到与ManyToMany关系相关的AND查询问题。我有类User,其中包含用户参与的线程列表和类MessageThread,其中包含特定线程中涉及的用户列表。

我的用户类:

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

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

类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)时,它总是返回相同的列表(因为我只有一个实体)现在)但是当使用AND查询时它会不断返回空列表

编辑:

这是根据提议的原始SQL查询为我工作的一个班轮。基本上也有在Ebean中可用的()方法/调用(我不知道我应该使用而不是和)

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

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

1 个答案:

答案 0 :(得分:0)

我通过创建自定义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;

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