Mongodb 如何在Morphia中缓存引用的实体?

Mongodb 如何在Morphia中缓存引用的实体?,mongodb,caching,dependency-injection,guice,morphia,Mongodb,Caching,Dependency Injection,Guice,Morphia,我正在使用MongoDB的Morphia和Stripes框架 让我们假设我有两个实体,Car(它描述了一辆特定的汽车,比如1984年的本田雅阁)和CarType(它指定了所有这类本田雅阁): 最自然的建模方式似乎是: @Entity class Car { @Id private String id; // VIN private Date purchaseDate; private Color color; @Reference private Car

我正在使用MongoDB的Morphia和Stripes框架

让我们假设我有两个实体,Car(它描述了一辆特定的汽车,比如1984年的本田雅阁)和CarType(它指定了所有这类本田雅阁):

最自然的建模方式似乎是:

@Entity 
class Car {
     @Id private String id; // VIN
     private Date purchaseDate;
     private Color color;
     @Reference private CarType type;

     // ..
}

@Entity
class CarType {
     @Id private String id;
     private String manufacturerId;
     private float engineDisplacement;

     // ..
}
这是可行的,但效率很低,因为每次装载汽车时都会从DB中查找CarType。我想在内存中缓存汽车类型,因为它们很少改变。像GORM和Hibernate这样的持久性框架将允许开箱即用,但我不确定在Morphia下如何做到这一点(有)

我希望保留对CarType的引用,因为仅仅存储字符串carTypeId会使视图和其他一切变得太复杂

所以我想我可以这样做:

@Entity 
class Car {
     @Id private String id; // VIN
     private Date purchaseDate;
     private Color color;
     private String typeId;

     @Transient private CarType type;
     @Transient private CarService service = new CarServiceImpl();

     public void setTypeId() {
         this.typeId = typeId;
         updateTypeReference();
     }

     @PostLoad void postLoad() {
         updateTypeReference();
     }

     private void updateTypeReference() {
         type = service.findTypeById(typeId);
     }

     // ..
}

class CarServiceImpl implements CarService {
     @CacheResult CarType findCarTypeId(String typeId) {
         datastore.get(CarType.class, typeId);
     }

     // ..
}
这是我想要的,但:

  • 看起来像是个黑客
  • 我想用Guice来注入服务,但不知道如何注入,尽管我在ActionBeans中有完整的依赖注入
因此,我想:

  • 了解如何将(最好是Guice)服务注入Morphia实体

  • 了解如何在Morphia中正确执行引用实体的缓存

  • 如果所有其他方法都失败,请切换到其他支持缓存的MongoDB POJO映射方法。但我真的很喜欢莫菲娅,所以我不想
      另一种常见的方法是在每辆车中嵌入CarType。这样,您只需获取单个实体

      权衡:

      • 您需要为所有重复的CarTypes提供更新逻辑。因为您说过它们几乎不会改变,所以这应该是良好的性能
      • 重复的数据需要额外的磁盘空间,RAM中的工作集也越来越大

      您需要评估这对您的数据是如何起作用的,但是为了加快读取速度而进行数据复制是一种非常常见的方法…

      因为我没有想到更好的解决方案,所以我正在使用@PostLoad事件处理程序,它从静态变量获取数据存储类,然后可以查找引用的实体


      这看起来像是一种黑客行为,要求数据存储服务是线程安全的,但它对我来说是有效的。

      是的,很好,这是另一种选择。但不适合我,因为在我的应用程序中,这些实际上不是汽车类型,所以即使这些数据很少更改(大约每月一次),当更改时,我必须更新和重新处理数百万个文档。对,如果您有数百万次重复,那么对于更新和保存磁盘/加载到RAM来说,这可能效率太低。