Mongodb Java:具有通用字段的Perist POJO类 [英] Mongodb java: Perist POJO class with generic field

查看:63
本文介绍了Mongodb Java:具有通用字段的Perist POJO类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看起来像这样的POJO类-

I have a POJO class which looks like this-

public class CacheEntity<V> {
  private String cacheId;
  private V value;

  public static final String ID_KEY = "cacheId";

  public CacheEntity() {
  }

  public CacheEntity(String cache_id, V value) {
    this.cacheId = cache_id;
    this.value = value;
  }

  public V getValue() {
    return value;
  }

  public void setValue(V value) {
    this.value = value;
  }

  public String getCacheId() {
    return cacheId;
  }

  public void setCacheId(String cacheId) {
    this.cacheId = cacheId;
  }
}

我正在使用官方驱动程序mongodb-driver-sync版本3.8.1

I am using official driver mongodb-driver-sync version 3.8.1

如文档这里,我将CodecRegistry与自动PojoCodecProvider一起使用.当我尝试保留此实体时,出现以下错误.

As mentioned in the documentation here, I am using CodecRegistry with automatic PojoCodecProvider. I am getting the following error when I try to persist this entity.

Exception in thread "main" org.bson.codecs.configuration.CodecConfigurationException: CacheEntity contains generic types that have not been specialised.
Top level classes with generic types are not supported by the PojoCodec.
    at org.bson.codecs.pojo.PojoCodecImpl.encode(PojoCodecImpl.java:93)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
    at com.mongodb.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:398)
    at com.mongodb.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:377)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
    at com.mongodb.internal.connection.BsonWriterHelper.writeDocument(BsonWriterHelper.java:75)
    at com.mongodb.internal.connection.BsonWriterHelper.writePayload(BsonWriterHelper.java:59)
    at com.mongodb.internal.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:143)
    at com.mongodb.internal.connection.RequestMessage.encode(RequestMessage.java:138)
    at com.mongodb.internal.connection.CommandMessage.encode(CommandMessage.java:57)
    at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:244)
    at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:99)
    at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:444)
    at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:72)
    at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:200)
    at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:269)
    at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:131)
    at com.mongodb.operation.MixedBulkWriteOperation.executeCommand(MixedBulkWriteOperation.java:418)
    at com.mongodb.operation.MixedBulkWriteOperation.executeBulkWriteBatch(MixedBulkWriteOperation.java:256)
    at com.mongodb.operation.MixedBulkWriteOperation.access$700(MixedBulkWriteOperation.java:67)
    at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:200)
    at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:191)
    at com.mongodb.operation.OperationHelper.withReleasableConnection(OperationHelper.java:419)
    at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:191)
    at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:67)
    at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:193)
    at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:960)
    at com.mongodb.client.internal.MongoCollectionImpl.executeReplaceOne(MongoCollectionImpl.java:602)
    at com.mongodb.client.internal.MongoCollectionImpl.replaceOne(MongoCollectionImpl.java:578)
    at com.mongodb.client.internal.MongoCollectionImpl.replaceOne(MongoCollectionImpl.java:567)

我该怎么做才能使它起作用?谢谢.

What can I do to make this work? Thank You.

推荐答案

有以下选项可以使其正常工作.

There are following options to make it working.

如果您每次都使用具体的泛型类型进行子类化,那么它将起作用:

If you subclass with concrete generic type each time, it works:

public class MyClassCacheEntity extends CacheEntity<MyClass> {}

使用BsonDocument + Jackson

为避免子类化,您可以尝试将任意对象存储为BsonDocument -s并使用Jackson对其进行序列化/反序列化:

By using BsonDocument + Jackson

To avoid subclassing you can try store arbitrary objects as BsonDocument-s and serialize/deserialize them using Jackson:

public class CacheEntity<V> {
  private String cacheId;
  private BsonDocument rawValue;

  // [...]

  // sets the value
  public void withValue(T o) {
    this.rawValue = BsonDocument.parse(new ObjectMapper().writeValueAsString(o))
  }

  // recovers the value
  public T value(Class<T> clazz) {
    return new ObjectMapper().readValue(this.rawValue.toJson(), clazz);
  }
}

这一直有效,直到您避免使用withValue()value()方法的getters/setters约定,否则Mongo开始抱怨相同的泛型问题.

This works until you avoid getters/setters convention for withValue() and value() methods, otherwise Mongo starts to complain about the same generics issue.

我认为,您也可以尝试使用org.bson.codecs.pojo.PojoCodec进行与上述相同的操作,您可以从当前的mongo编解码器注册表中创建或提取.如果您事先知道并提供了真实的类,那么它就不会抱怨泛型.

I think, you can also try to do it the same as above using org.bson.codecs.pojo.PojoCodec which you can either create or extract from the current mongo codecs registry. If you know in advance and give it the real class, it shouldn't complain about generics.

这篇关于Mongodb Java:具有通用字段的Perist POJO类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆