简体   繁体   English

如何使用 Hibernate JoinFormula Annotation 进行多态查询?

[英]How make a polymorphic query with Hibernate JoinFormula Annotation?

I try to find the best way to implement a calculated property witch query the latest message into the chat entity.我试图找到实现计算属性的最佳方法,将最新消息查询到聊天实体中。

The Message entity is implemented as a class hierarchy according to the type of the message (Image, Text, Url...)根据消息的类型(图像、文本、Url...),消息实体实现为 class 层次结构

@Entity
@Table(name = MessageEntity.TABLE_NAME)
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "Type", discriminatorType = DiscriminatorType.STRING)
@NamedEntityGraphs({
    @NamedEntityGraph(name = MessageEntity.GRAPH_MESSAGES_FULL, attributeNodes = {
        @NamedAttributeNode(value = "creator", subgraph = UserEntity.GRAPH_USER_BASIC),
        @NamedAttributeNode(value = "chat")
    })
})
@Getter
@Setter
public abstract class MessageEntity extends AbstractEntity

MessageImageEntity example MessageImageEntity 示例

@Entity
@Table(name = MessageImageEntity.TABLE_NAME)
@DiscriminatorValue("IMAGE")
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
public class MessageImageEntity extends MessageEntity

Therefore I have implemented the follow JoinFormula property for get last message into the Chat but the Message Entity that was get does not belong to a specific implementation因此,我实现了以下 JoinFormula 属性以将最后一条消息获取到聊天中,但获取的消息实体不属于特定实现

@ManyToOne(fetch = FetchType.LAZY)
    @JoinFormula("("
            + "SELECT M.Messages_id "
            + "FROM Messages M "
            + "LEFT OUTER JOIN Messages_Image MI ON M.Messages_id = MI.Messages_id "
            + "LEFT OUTER JOIN Messages_Text MT ON M.Messages_id = MT.Messages_id  "
            + "LEFT OUTER JOIN Messages_Url MU ON M.Messages_id = MU.Messages_id  "
            + "WHERE M.Chat_id = Chats_id "
            + "ORDER BY M.Created_at DESC "
            + "LIMIT 1"
            + ")")
    protected MessageEntity lastMessage;

Somebody know How Can I do this query?有人知道我该怎么做这个查询? Thanks, Greetings谢谢,问候

I'd say the best approach is to use DTOs for this, which is a perfect use case forBlaze-Persistence Entity Views .我想说最好的方法是为此使用 DTO,这是Blaze-Persistence Entity Views的完美用例。

Blaze-Persistence is a query builder on top of JPA which supports many of the advanced DBMS features on top of the JPA model. Blaze-Persistence 是 JPA 之上的查询构建器,它支持 JPA model 之上的许多高级 DBMS 功能。 I created Entity Views on top of it to allow easy mapping between JPA models and custom interface defined models, something like Spring Data Projections on steroids.我在它上面创建了实体视图,以便在 JPA 模型和自定义接口定义模型之间轻松映射,例如 Spring 数据投影。 The idea is that you define your target structure the way you like and map attributes(getters) via JPQL expressions to the entity model.这个想法是您以您喜欢的方式定义您的目标结构,并通过 JPQL 表达式将 map 属性(getter)定义到实体 model。 Since the attribute name is used as default mapping, you mostly don't need explicit mappings as 80% of the use cases is to have DTOs that are a subset of the entity model.由于属性名称用作默认映射,因此您通常不需要显式映射,因为 80% 的用例是拥有作为实体 model 子集的 DTO。

A DTO mapping for your model could look as simple as the following model 的 DTO 映射看起来很简单,如下所示

@EntityView(MessageEntity.class)
interface MessageEntityDto {
    Integer getId();
    // Other fields
}
@EntityView(Chat.class)
interface ChatDto {
    Integer getId();
    @Limit(limit = "1", order = "created DESC")
    @Mapping("messages")
    MessageEntityDto getLatestMessage();
}

Querying is a matter of applying the entity view to a query, the simplest being just a query by id.查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

ChatDto dto = entityViewManager.find(entityManager, ChatDto.class, id);

But the Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features但是 Spring 数据集成允许您几乎像 Spring 数据投影一样使用它: https://persistence.blazebit.com/documentation/entity-view/mandata-features_html/index。

It will only fetch the mappings that you tell it to fetch它只会获取您告诉它获取的映射

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM