如何使用弹簧数据将 BigInteger 转换为 Objectid

Posted

技术标签:

【中文标题】如何使用弹簧数据将 BigInteger 转换为 Objectid【英文标题】:How to convert a BigInteger to Objectid with spring data 【发布时间】:2016-06-04 17:31:23 【问题描述】:

我使用 java 8 和以下 spring 规范:

<spring.version>4.2.3.RELEASE</spring.version>
<spring.security.version>4.0.3.RELEASE</spring.security.version>
<spring.data.version>1.8.1.RELEASE</spring.data.version>

我有一个显然有 _id 的文档,它运行良好,但我有另一个字段存储另一个 _id 的引用,这是我预期的 JSON


    "_id" : ObjectId("56c8f330d4c65e543ceac8de"),
    "companyId" : ObjectId("56c8f330d4c65e543ce8c8de"),
    "name" : "COMPANY S.R.L",
    more fields......

我创建了以下转换器:

 @Component
   public class PurchaseWriterConverter implements Converter<Purchase, DBObject>
   
       @Override public DBObject convert(Purchase source)
        
        DBObject dbo = new BasicDBObject();
        dbo.put("_id", source.getId());
        **ObjectId objCompany = new ObjectId(source.getCompany().toString(16));
        dbo.put("company", objCompany);**
        dbo.put("supplier", source.getSupplier());
        dbo.put("status", source.getStatus().toString());
        dbo.put("attendant", source.getAttendant());
        dbo.put("cashier", source.getCashier());

        List<Object> orders = new BasicDBList();

        for (OrderWrapper order : source.getOrders())
        
            DBObject orderDBObject = new BasicDBObject();
            orderDBObject.put("description", order.getDescription());
            orderDBObject.put("basePrice", order.getBasePrice());
            orderDBObject.put("grossWeight", order.getGrossWeight());
            orderDBObject.put("netWeight", order.getNetWeight());
            orderDBObject.put("subtotal", order.getSubtotal());
            orderDBObject.put("totalWeight", order.getTotalWeight());
            orders.add(orderDBObject);
        
        dbo.put("orders", orders);
        dbo.put("createDate", source.getCreateDate());
        dbo.put("updateDate", source.getUpdateDate());
        dbo.put("approvedBy", source.getApprovedBy());
        dbo.put("createDate", source.getCreateDate());
        dbo.put("updateDate", source.getUpdateDate());
        dbo.removeField("_class");

        return dbo;
    

以下行不起作用

dbo.put("_id", source.getId()); **ObjectId objCompany = new ObjectId(source.getCompany().toString(16));

所以,我尝试创建另一个转换器,以便将 BigInteger 转换为 ObjectId,就像这样

公共类 BigIntegerToObjectIdConverter 实现 Converter

@Override
public ObjectId convert(BigInteger source) 
    return source == null ? null : new ObjectId(source.toString());

但我得到了同样的错误:

org.springframework.core.convert.ConversionFailedException: Failed to convert from type com.xxxxxxxxxxx.entity.Purchase to type com.mongodb.DBObject for value 'Purchasecompany=1, orders=[com.xxxxxxx.equilibrium.wrapper.OrderWrapper@9cd3f65], supplier=26857458392532697059830357595, approvedBy='', status=TO_BE_APPROVED, attendant='User Admin', cashier='''; nested exception is java.lang.IllegalArgumentException: invalid ObjectId [1]

我作为大整数发送的值是“1”。

谁能给我一些关于如何将 BigInteger 转换为 ObjectId 的指导或提出不同的建议。

【问题讨论】:

您为什么要尝试将数值转换为 ObjectId?为什么不直接将数值存储到_id 字段中?没有什么说 _id 必须包含 ObjectId 类型。 companyId 是存储在不同数据库(mysql db)中的 id。我需要将此引用存储在我的收藏中,因为我需要按公司创建查询。如果你注意到我已经声明了工作正常的 _id,现在我需要存储另一个 biginteger 值。 这里是错误invalid ObjectId [1],这里是代码ObjectId objCompany = new ObjectId(source.getCompany().toString(16))。很明显.getCompany() 甚至.toString(16) 的十六进制转换都没有返回ObjectId() 的有效值。因此,在那里阅读一下应该会告诉您这不仅仅是要求数字的十六进制表示的问题。所以尝试转换为ObjectId 显然是错误的。随便用什么类型就行了,不难理解。 如果你阅读了描述我也尝试创建一个基本的转换器 Biginteger 到 ObjectId,.tostring(16) 是错误的,你是对的,但错误是一样的 整个概念是错误的。您不能以任何方式将任何类型的“数字”值转换为ObjectId。那就是你在这里做错了。这就是我耐心地向你解释的概念,所以你明白为什么你不能也不应该这样做。最后一条评论中有一个链接可以解释ObjectId 的确切含义,您应该阅读该链接以获得进一步的理解。 【参考方案1】:

我刚刚在这里https://***.com/a/46508892/4660481回答了一个类似的问题

一个有效的ObjectId 可以由正好24 个十六进制字符构成。在这种情况下,您的 .toString(16) 将返回长度不是 24 的 "1"。在这种情况下,您想要的是 "000000000000000000000001"。您可以通过填充 0 来解决此问题:

String hexString24 = StringUtils.leftPad(source.getCompany().toString(16), 24, "0");
ObjectId objCompany = new ObjectId(hexString24);

【讨论】:

以上是关于如何使用弹簧数据将 BigInteger 转换为 Objectid的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中怎么把int型数据转为BigInteger型数据

graphene-django 将 models.BigInteger() 转换为 graphene.Integer()

如何在 Java 中将语言环境格式的数字转换为 BigInteger?

如何从 Java 中的 BigInteger 获取无符号字节数组?

java中BigDecimal和bigInteger如何转换

JOOQ 强制类型将 BigInteger 转换为 BigDecimal 以用于 POSTGRES