当前位置: 首页 > 知识库问答 >
问题:

JpaSagaStore与Jackson一起无法正确存储状态

宦博超
2023-03-14

在SpringBoot应用程序中,我有以下配置:

axon:
  axonserver:
    servers: "${AXON_SERVER:localhost}"
  serializer:
    general: jackson
    messages: jackson
    events: jackson

logging.level:
  org.axonframework.modelling.saga: debug

将场景缩小到最小,佐贺类的相关部分:

@Slf4j
@Saga
@ProcessingGroup("AuctionEventManager")
public class AuctionEventManagerSaga {
    @Autowired
    private transient EventScheduler eventScheduler;

    private ScheduleToken scheduleToken;
    private Instant auctionTimerStart;

    @StartSaga
    @SagaEventHandler(associationProperty = "auctionEventId")
    protected void on(final AuctionEventScheduled event) {
        this.auctionTimerStart = event.getTimerStart();

        // Cancel any pre-existing previous job, since the scheduling thread might be lost upon a crash/restart of JVM.
        if (this.scheduleToken != null) {
            this.eventScheduler.cancelSchedule(this.scheduleToken);
        }

        this.scheduleToken = this.eventScheduler.schedule(
            this.auctionTimerStart,
            AuctionEventStarted.builder()
                .auctionEventId(event.getAuctionEventId())
                .build()
        );
    }

    @EndSaga
    @SagaEventHandler(associationProperty = "auctionEventId")
    protected void on(final AuctionEventStarted event) {
        log.info(
            "[AuctionEventManagerSaga] Current state: {scheduleToken={}, auctionTimerStart={}}",
            this.scheduleToken,
            this.auctionTimerStart
        );
    }
}
@Value
@Builder
@JsonDeserialize(builder = AuctionEventStarted.AuctionEventStartedBuilder.class)
public class AuctionEventStarted {
    AuctionEventId auctionEventId;

    @JsonPOJOBuilder(withPrefix = "")
    public static final class AuctionEventStartedBuilder {}
}
2020-05-12 15:40:01.180 DEBUG 1 --- [mandProcessor-4] o.a.m.saga.repository.jpa.JpaSagaStore   : Updating saga id c8aff7f7-d47f-4616-8a96-a40044cb7e3b as {}

1-Axon如何安全地管理Jackson忽略@autowired、来自@saga类的瞬态和静态属性?我尝试在非状态属性上手动定义@jsonignore,但仍然不起作用。

2-Axon安全地将XStream配置为忽略内部类(主要是作为私有静态final实现的构建器类)?

提前感谢,

    @Override
    public Class<AuctionEventManagerSaga> handledType() {
        return AuctionEventManagerSaga.class;
    }

    @Override
    public void serialize(
        final AuctionEventManagerSaga value,
        final JsonGenerator gen,
        final SerializerProvider serializers
    ) throws IOException {
        gen.writeStartObject();
        gen.writeObjectField("scheduleToken", value.eventScheduler);
        gen.writeObjectField("auctionTimerStart", value.auctionTimerStart);
        gen.writeEndObject();
    }
2020-05-12 16:20:01.322 DEBUG 1 --- [mandProcessor-0] o.a.m.saga.repository.jpa.JpaSagaStore   : Storing saga id c4b5d94c-7251-40a5-accf-332768b1cacd as {"delegatee":null,"unwrappingSerializer":false}
2020-05-12 17:08:06.495 DEBUG 1 --- [ault-executor-0] o.a.a.c.command.AxonServerCommandBus     : Received command response [message_identifier: "79631ffb-9a87-4224-bed3-a957730dced7"
error_code: "AXONIQ-4002"
error_message {
  message: "No converter available\n---- Debugging information ----\nmessage             : No converter available\ntype                : jdk.internal.misc.InnocuousThread\nconverter           : com.thoughtworks.xstream.converters.reflection.ReflectionConverter\nmessage[1]          : Unable to make field private static final jdk.internal.misc.Unsafe jdk.internal.misc.InnocuousThread.UNSAFE accessible: module java.base does not \"opens jdk.internal.misc\" to unnamed module @7728643a\n-------------------------------"
  location: "1@600b5b87a922"
  details: "No converter available\n---- Debugging information ----\nmessage             : No converter available\ntype                : jdk.internal.misc.InnocuousThread\nconverter           : com.thoughtworks.xstream.converters.reflection.ReflectionConverter\nmessage[1]          : Unable to make field private static final jdk.internal.misc.Unsafe jdk.internal.misc.InnocuousThread.UNSAFE accessible: module java.base does not \"opens jdk.internal.misc\" to unnamed module @7728643a\n-------------------------------"
}
request_identifier: "2f7020b1-f655-4649-bbe0-d6f458b3c2f3"
]
2020-05-12 17:08:06.505  WARN 1 --- [ault-executor-0] o.a.c.gateway.DefaultCommandGateway      : Command 'ACommandClassDispatchedFromSaga' resulted in org.axonframework.commandhandling.CommandExecutionException(No converter available
---- Debugging information ----
message             : No converter available
type                : jdk.internal.misc.InnocuousThread
converter           : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
message[1]          : Unable to make field private static final jdk.internal.misc.Unsafe jdk.internal.misc.InnocuousThread.UNSAFE accessible: module java.base does not "opens jdk.internal.misc" to unnamed module @7728643a
-------------------------------)

仍然没有解决这个问题的运气...

共有1个答案

云项禹
2023-03-14

我在Axon系统上工作过,其中唯一使用的serializer实现也是jacksonserializer。不过请注意,这不是Axon团队推荐的。对于消息(即命令、事件和查询),使用JSON作为序列化格式非常有意义。但是,将通用的序列化程序切换到jackson意味着您必须在域逻辑(例如,您的Saga)中添加jackson的细节“以使其工作”。

不管怎样,回溯到我成功的Jackson-Serialized-Sagas用例。在本例中,我们在想要考虑的字段(实际状态)上使用了正确的JSON注释匹配,并忽略了我们不想反序列化的字段(使用transient@jsonignore)。为什么两者在您的场景中似乎都不起作用,在这个阶段还不完全清楚。

我记得的是,被引用项目的团队非常清楚地决定反对Lombok,因为当涉及到去/序列化时,“总体上很奇怪”。因此,作为一个尝试,在Saga类中不使用任何Lombok注释/逻辑是值得的,看看在这种状态下是否可以正确地解/序列化它。

我知道这不是一个确切的答案,但我希望它能帮助你无论如何!可能值得共享发生此问题的存储库;可能也会让其他人更清楚这个问题。

 类似资料:
  • 问题内容: 我正在使用 mysql dbms存储来自Wikipedia的页面。我已使用指令在my.cnf文件中将字符集编码设置为(维基百科编码): 并使用属性定义创建了我的数据库。 我还通过以下方式更改了mysqld客户端的字符集编码: 在初始化我的jdbc驱动程序时插入属性。 进行查询 但是我注意到mysql服务器用其他字符替换了一些字符。 例如,它替换为。 更新 我已经运行的命令确保这两个和的

  • 问题内容: 抱歉,我真的很想念React中子组件内部的传递。 我已经实现了一个包含3个组件的待办事项列表。 有一个组成部分和一个组成部分。状态仅存储在组件中。 显示器起步不错,因此可以看到道具。但是在提交表单后,我收到了以下错误: TypeError:this.props.tasks.map不是函数 当我console.log时,我没有得到我的数组,而是数组的长度。 你知道为什么吗? 编辑 :谢谢

  • 本文向大家介绍Android SharedPreferences存储的正确写法,包括了Android SharedPreferences存储的正确写法的使用技巧和注意事项,需要的朋友参考一下 SharedPreferences 特点 即便是Android小白都知道的SharedPreferences的用法,这是保存数据最简便的方法,但是不处理好的话后期维护将是一个巨大的坑。那么该如何处理好Shar

  • 我对scrollview和GeometryReader有一些问题。我想要一张图片下的物品清单。每个项目都应该有以下宽度和高度: 我为我的用例尝试了两种方法。这是我的第一个代码结构: 我正在使用几何体读取器来获取VStack的宽度,因为它有一个填充,我不想获得滚动视图的全宽。 但对于GeometryReader,UI上只显示ForEach循环中的最后一项。而GeometryReader只有很小的高度

  • 问题内容: 片段对于将UI逻辑分为一些模块来说似乎非常好。但是随着它的生命周期,我仍然迷茫。因此,非常需要大师的想法! 编辑 请参阅下面的愚蠢解决方案;-) 范围 主要活动有一个带有片段。这些片段可以为其他(子主)活动实现一些不同的逻辑,因此片段的数据通过活动内部的回调接口填充。并且所有功能在首次启动时都正常,但是! 问题 重新创建活动时(例如,在方向更改时),的片段也是如此。代码(您将在下面找到

  • 问题内容: 在我编写的flask应用程序中,我使用了一个外部库,该库可以使用环境变量进行配置。注意:我自己编写了这个外部库。因此,如有必要,我可以进行更改。从命令行运行时,运行带有以下内容的烧瓶服务器: 一切都如预期。但将它部署到Apache后,用它不工作了。事实上,打印出到(所以它在Apache日志中显示出来显示,该wsgi过程似乎是在一个非常不同的环境(一个,好像是这样了。其实,它指向我的发展