gpt4 book ai didi

java - 对每个实体子类型使用不同的投影

转载 作者:行者123 更新时间:2023-12-02 03:59:59 25 4
gpt4 key购买 nike

是否可以通过子类型和 Spring Data REST 定义不同的投影使用关于类类型的最具体的投影?

此问题已在 JIRA 问题 DATAREST-739 上曝光并且还存在合并提交,但这没有出现在官方 changelog 上而且我也没有找到任何文档或指南来解决当前版本的问题。

问题中使用的用例示例是:

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="type")
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
public abstract class Message implements Identifiable<UUID> { ... }

@Entity
@DiscriminatorValue("TEXT")
@JsonTypeName("TEXT")
public class TextMessage extends Message { ... }

@Entity
@DiscriminatorValue("TODO")
@JsonTypeName("TODO")
public class TodoMessage extends Message { Boolean isDone; }

@Projection(name = "summary", types = TodoMessage.class)
public class TodoMessageSummary { Boolean getIsDone(); }

@Projection(name = "summary", types = TextMessage.class)
public class TextMessageSummary { ... }

public interface MessageRepo extends JpaRepository<Message, UUID> { ... }

@RepositoryRestResource(excerptProjection = TodoMessageSummary.class)
public interface TodoMessageRepo extends JpaRepository<Message, UUID> { ... }

@RepositoryRestResource(excerptProjection = TextMessageSummary.class)
public interface TextMessageRepo extends JpaRepository<TextMessage, UUID> { ... }

第一个问题:如何定义 MessageRepo 的摘录投影,以便对 TodoMessage 实体使用 TodoMessageSummary,对 TextMessage 使用 TextMessageSummary?

第二个问题:如何为另一个具有 Message 字段的实体定义投影?假设您有以下内容:

@Projection(name = "summary", types = Dashboard.class)
public class DashboardSummary {
List<Message> getMessages();
}

已解决:

最佳答案

技巧是在子类型投影中使用继承:

@Projection(name = "summary", types = Message.class)
public class MessageSummary {
@Value("#{target.getClass().getSimpleName()}")
String getType();
}

@Projection(name = "summary", types = TextMessage.class)
public class TextMessageSummary extends MessageSummary { ... }

@Projection(name = "summary", types = TodoMessage.class)
public class TodoMessageSummary extends MessageSummary {
Boolean getIsDone();
}

Spring REST @RepositoryRestResource 使用具体子类型投影返回消息数组( isDone 必须出现在 TodoMessage 实例中)

如果您需要将相同的内容添加到 Controller 中的扩展 @RequestMapping 中,那么这个问题会更复杂,为此我使用下一个 snnipeed:

    Page<Message> results = repository.findAll(predicate, pageable);
Converter<? super Message, ? extends MessageSummary> converter= l -> {
if(l instanceof TextMessage){
return projectionFactory.createProjection(TextMessageSummary.class,l);
}
else if(l instanceof TodoMessage){
return projectionFactory.createProjection(TodoMessageSummary.class,l);
}
else {
return projectionFactory.createProjection(MessageSummary.class,l);
}
};
Page<MessageSummary> projected =results.map(converter);
return pagedAssembler.toResource(projected);

请注意,如果前端仅需要资源类型信息用于只读目的(即对于POST/PUT使用具体子类型端点),我认为实际上并不需要使用@JsonTypeInfo 因为在投影中使用 SpEL 可以更轻松、更灵活地获取此类型信息:

@Value("#{target.getClass().getSimpleName()}")
String getType();

关于java - 对每个实体子类型使用不同的投影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42326676/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com