JPQL:对于带有联接的查询,验证失败

问题描述

我正在努力使查询在JPQL中工作。

我有以下实体(已分解):

对话
一次对话有很多讯息。
一个对话中有许多UserConversations。

@Entity
@Table(name = "conversations")
data class Conversation(
    @Column(nullable = false)
    var createdAt: LocalDateTime = LocalDateTime.Now(),@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: IDType = 0
) {
    @OnetoMany(mappedBy = "conversation")
    lateinit var messages: MutableSet<Message>

    @OnetoMany(mappedBy = "conversation")
    lateinit var userConversation: MutableSet<UserConversation>
}

消息
许多邮件只有一个对话。

@Entity
@Table(name = "messages")
data class Message(
    @Column(nullable = false)
    var createdAt: LocalDateTime = LocalDateTime.Now(),@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: IDType = 0
) {
    @ManyToOne(cascade = [CascadeType.MERGE],optional = false)
    @JoinColumn(name = "conversation_id",nullable = false)
    lateinit var conversation: Conversation
}

用户对话
许多UserConversation只有一个对话。

@Entity
@Table(name = "user_conversations")
data class UserConversation(
    @Column(nullable = false)
    var createdAt: LocalDateTime = LocalDateTime.Now(),@Column(nullable = false)
    var allowHistory: Boolean = true,nullable = false)
    lateinit var conversation: Conversation
}

为了帮助您了解这些实体,请考虑频道或群聊。
对话就是这样一个小组。
一条消息被发布到该组。
UserConversation描述了用户与此类群组之间的关系。

我要实现的方案:
如果不允许允许用户查看对话历史记录,则仅显示其加入后的消息。

本机解决方案看起来像这样:

SELECT     messages.*,user_conversations.*
FROM       messages

INNER JOIN user_conversations
        ON messages.conversation_id = user_conversations.conversation_id

WHERE      user_conversations.id IN (42) # I might want to fetch multiple userConversations at once
AND        messages.created_at >= IF(user_conversations.allow_history,messages.created_at,user_conversations.created_at)

我想将其放置在JPA存储库中。
因为我最初是为Messages获取消息的,所以我一直在考虑将其放入MessageRepository(这不是必须的)。

稍后我需要能够将userConversations链接到他们的消息,因此我尝试引入自定义结果:

// query here
fun findAllByUserConversationIdIn(userConversationIds: Collection<IDType>): Collection<UserConversationMessage>

interface UserConversationMessage {
    val message: Message
    val userConversation: UserConversation
}

这是我想出的JPQL:

SELECT
    m as message,uc as userConversation
FROM
    Message m
INNER JOIN UserConversation uc
    ON uc.conversation.id = m.conversation.id
WHERE uc.id IN (?1)
AND m.createdAt >= CASE WHEN uc.allowHistory THEN m.createdAt ELSE uc.createdAt END

但是验证失败。

你能帮我吗?

欢呼

解决方法

它可能是如此简单。 我的JPQL实际上还不错。 错误在这里:

AND m.createdAt >= CASE WHEN uc.allowHistory THEN m.createdAt ELSE uc.createdAt END

应该是

AND m.createdAt >= CASE WHEN uc.allowHistory = 1 THEN m.createdAt ELSE uc.createdAt END

我很惊讶该查询实际上返回了我想要的东西。