【问题标题】:Mongojack: invalid hexadecimal representation of an ObjectIdMongojack:ObjectId 的无效十六进制表示
【发布时间】:2021-05-17 21:19:53
【问题描述】:

目标

我正在尝试使用mongojack 将一些数据推送到 mongo db。 我希望结果在数据库中是这样的:

{
 "_id": "840617013772681266",
 "messageCount": 69420,
 "seedCount": 18,
 "prefix": "f!",
 "language": "en"
}

问题

相反,我在控制台中收到此错误。

Caused by: java.lang.IllegalArgumentException: invalid hexadecimal representation of an ObjectId: [840617013772681266]
    at org.bson.types.ObjectId.parseHexString(ObjectId.java:390)
    at org.bson.types.ObjectId.<init>(ObjectId.java:193)
    at org.mongojack.internal.ObjectIdSerializer.serialiseObject(ObjectIdSerializer.java:66)
    at org.mongojack.internal.ObjectIdSerializer.serialize(ObjectIdSerializer.java:49)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770)
    ... 59 more

代码

这是我尝试在数据库中创建新公会时调用的代码:

    public static Guild getGuild(String id) throws ExecutionException {
        return cache.get(id);
    }

cache 如下(加载被执行):

    private static LoadingCache<String, Guild> cache = CacheBuilder.newBuilder()
            .expireAfterAccess(10, TimeUnit.MINUTES)
            .build(
                    new CacheLoader<>() {
                        @Override
                        public Guild load(@NotNull String id) {
                            return findGuild(id).orElseGet(() -> new Guild(id, "f!"));
                        }
                    });

首先被调用的findGuild 方法:

    public static Optional<Guild> findGuild(String id) {
        return Optional.ofNullable(guildCollection.find()
                .filter(Filters.eq("_id", id)).first());
    }

最后是Guild 文档。

@Getter
@Setter
public class Guild implements Model {

    public Guild(String id, String prefix) {
        this.id = id;
        this.prefix = prefix;
    }

    public Guild() {
    }

    private String id;

    /*
    If a Discord guild sent 1,000,000,000 messages per second,
    it would take roughly 292471 years to reach the long primitive limit.
     */
    private long messageCount;

    private long seedCount;

    // The default language is specified in BotValues.java's bot.yaml.
    private String language;

    private String prefix;

    @ObjectId
    @JsonProperty("_id")
    public String getId() {
        return id;
    }

    @ObjectId
    @JsonProperty("_id")
    public void setId(String id) {
        this.id = id;
    }
}

我尝试过的

我尝试了多种方法,例如 Long.toHexString(Long.parseLong(id)),事实是我不完全理解错误,在看到 documentation 之后,我留下的问题多于答案。

【问题讨论】:

  • 请向我转发有关我可能未在此处显示的代码的任何问题。

标签: json mongodb pojo mongojack


【解决方案1】:

ObjectId 是一个 12 字节的值,通常表示为 24 个十六进制数字的序列。它不是整数。

您可以使用适当的 ObjectId 构造函数创建 ObjectId 值,也可以解析 24 位十六进制数字字符串。您似乎正在尝试执行到 ObjectId 的整数转换,这通常不是受支持的操作。

从技术上讲,您可以通过将整数 840617013772681266 填充为 12 个字节来将整数 840617013772681266 转换为 ObjectId,但标准 MongoDB 驱动程序工具不会为您执行此操作,并且会认为此无效输入(作为整数或字符串) ) 用于转换为 ObjectId。

Ruby 中的示例:

irb(main):011:0> (v = '%x' % 840617013772681266) + '0' * (24 - v.length)
=> "baa78b862120032000000000"

请注意,虽然结果值可以解析为 ObjectId,但它不是按照 ObjectId 规则构造的,因此无法将值合理地分解为 ObjectId 组件(机器 ID、计数器和随机值)。

【讨论】:

  • id 是一个字符串,我试过 Long.toHexString。我也尝试使用 ObjectId 构造函数,但无济于事。我在您的回答中遗漏了 100% 的内容。
  • "840617013772681266" 不能使用标准驱动工具转换为 objectid,无论它是存储在字符串还是整数中。
  • 您如何建议我继续使用您在回答中提到的零填充方法?
猜你喜欢
  • 1970-01-01
  • 2016-02-06
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 2014-10-12
  • 2016-03-05
相关资源
最近更新 更多