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

时间:2012-12-24 22:48:46

标签: mongodb caching dependency-injection guice morphia

我正在使用Morphia for MongoDB with Stripes Framework。

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

最自然的模拟方法似乎是:

@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;

     // ..
}

这是有效的,但是效率很低,因为每次加载Car时都会从DB中查找CarType。我想将汽车类型缓存在内存中,因为它们很少变化。像GORM和Hibernate这样的持久性框架允许开箱即用,但我不确定如何在Morphia下进行(有a feature request raised for that)。

我想保留对CarType的引用,因为只存储一个String 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注入服务,但无法弄清楚如何,尽管我在Stripes ActionBeans中使用了整体依赖注入。

所以我想要:

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

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

  • 如果所有其他方法都失败了,请切换到支持缓存的其他MongoDB POJO映射方法。但我真的很喜欢Morphia所以我宁愿不喜欢。

2 个答案:

答案 0 :(得分:1)

另一种常见的方法是将CarType嵌入每辆车中。这样你只需要获取一个实体。

权衡:

  • 您需要为所有重复的CarTypes提供更新逻辑。既然你说他们几乎没有改变,那么这应该是很好的表现。
  • 重复数据需要额外的磁盘空间,RAM中的工作集也会变大。

您需要评估这对您的数据的影响,但数据重复以使读取更快是一种非常常见的方法......

答案 1 :(得分:0)

由于我没有想到更好的解决方案,我正在做一个@PostLoad事件处理程序,它从静态变量获取数据存储类,然后可以查找Referenced实体。

这看起来像是一个黑客,需要数据存储区服务是线程安全的,但它对我有用。