0

我正在将 Morphia 用于带有 Stripes 框架的 MongoDB。

让我们假设我有两个实体,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;

     // ..
}

这可行,但效率低下,因为每次加载 Car 时都会从 DB 中查找 CarType。我想在内存中缓存汽车类型,因为它们很少改变。像 GORM 和 Hibernate 这样的持久性框架可以开箱即用,但我不确定如何在 Morphia 下做到这一点(为此提出了一个功能请求)。

我想保留对 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 中有整体依赖注入工作。

所以我想:

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

或者

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

或者

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

2 回答 2

1

另一种常见的方法是将 CarType 嵌入到每个 Car 中。这样,您只需要获取一个实体。

权衡:

  • 您将需要所有重复的 CarType 的更新逻辑。既然你说它们几乎没有变化,这在性能方面应该很好。
  • 重复的数据需要额外的磁盘空间,并且 RAM 中的工作集也会变得更大。

您需要评估这对您的数据有何影响,但数据复制以加快读取速度是一种非常常见的方法......

于 2012-12-25T01:50:10.223 回答
0

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

这似乎是一种 hack,需要数据存储服务是线程安全的,但它对我有用。

于 2013-01-04T10:50:52.557 回答