【发布时间】:2020-09-22 03:58:21
【问题描述】:
我有这个factory 收藏:
@Document(collection = "factory")
public class Factory
{
Private List<Product> products;
}
将Product 作为产品嵌入。
当我必须向现有工厂添加产品时:
@Autowired
private FactoryRepository factoryRepository;
public void addProduct(Long id, Product product) {
Factory f = factoryRepository.findById(id);
f.addProduct(product);
factoryRepository.save(f);
}
但是,问题是产品是一个包含一组重属性的大型对象,而工厂可以拥有 2000 个产品。
因此,检索到的工厂会导致大量内存消耗,尽管在此阶段不需要。有没有办法在不读取整个对象的情况下直接将新产品对象附加到工厂文档中?
编辑:
至于cmets,我试过了:
public void addProduct(Long id, Product product) {
Document find = new Document("_id",id);
Document listItem = new Document("products",product);
Document push = new Document("$push", listItem);
collection.updateOne(find,push);
}
这给出了错误:
org.bson.codecs.configuration.CodecConfigurationException:
Can't find a codec for class product
所以我修改为在推送之前将其转换为字符串:
public void addProduct(Long id, Product product) {
Document find = new Document("_id",id);
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
Document listItem = new Document("products",ow.writeValueAsString(product));
Document push = new Document("$push", listItem);
collection.updateOne(find,push);
}
这个推送对象正确但是在读取时:
org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting from type [java.lang.String] to type [Product]
不过,我在这里无处。有关解决此问题的任何想法?
【问题讨论】:
-
您可以尝试为这种情况实施不同的更新操作。这能解决你的问题吗? stackoverflow.com/questions/15436542/…
-
不,直接将此产品对象转换为文档非常困难。寻找自动映射属性的解决方案
-
您的集合
factory中有多少Factory对象?是否只有一家工厂拥有所有产品?如果是这样,您应该使用集合products代替,您可以在其中直接插入Product对象。 -
可以有大约 1200 个工厂对象
-
你不关心并发更新吗?如果 2 个不同的线程同时将产品推送到同一工厂,则有可能丢失其中一个更新。 $push 解决了这两个问题。
标签: java mongodb spring-boot