0

我们正在向我们的应用程序添加修订历史记录,并且在将归档文档嵌入我们的历史记录对象时遇到了一些问题。我们的状态是这样的:

@ToString
@EqualsAndHashCode
@Entity("bookOrder")
@Converters({DateTimeConverter.class, LocalDateConverter.class})
public class BookOrderState {
    @Id
    @Getter
    private Long id;

    @Indexed
    @Getter
    private final BookOrderStatus status;

    @Getter private Long version;
...

我们的历史对象看起来像:

@ToString
@Entity("bookOrderHistory")
@Converters(DateTimeConverter.class)
public class BookOrderStateHistory {

    @Id
    @Getter
    private String id;

    @Getter
    private DateTime createdDate;

    @Getter
    private BookOrderState bookOrder;
...

当我们更新一个订单时,我们从数据库中获取它的当前状态,将它包装在一个历史对象中,该对象获取它自己的 id 和时间戳,并将新bookOrderStateHistory的和更新的都保存bookOrderState到数据库中。此过程正确写入,但在检索时,我们最终会得到多个具有相同bookOrderState. 我们将其追溯到@IdBookOrderState 上。由于许多历史对象将具有相同的状态对象_id(但对象的实际状态有所不同),吗啡似乎假设它们都应该获得相同的状态对象。我们已经一起破解了一种方法来拦截嵌入的状态对象并将其切换_id到仅id在写入时(以及在读取时相反的方式),但这感觉是错误的。

Tl; 博士:有没有一种简单的方法可以防止 morphiaid -> _id在另一个文档中时对对象进行操作?

4

1 回答 1

1

我正在使用 Morphia 做几乎完全相同的事情,并且没有遇到任何问题。我在上面的代码中没有看到它,但如果“bookOrder”属性用@Reference 注释,那么你会看到你描述的行为。如果你不放@Reference,Morphia 似乎默认为@Embedded,所以你应该没问题。
我有一个名为“Snapshot”的简单类,用于存储对象的历史记录:

@Entity("snapshots")
public class Snapshot<T>
{
  @Id
  protected ObjectId id;

  @Embedded
  protected T data;
}

每当对象更改时,我都会创建它的快照并将快照保存到数据库中。使用以下简单的测试用例,我似乎得到了正确的行为:

Point pt = new Point();
pt.setLatitude( 40.0 );
pt.setLongitude( 40.0 );

ds.save( pt ); //ds is Datastore

Snapshot<Point> ts1 = new Snapshot<Point>();
ts1.setData( pt );
ds.save( ts1 );

pt.setLatitude( 50.0 );
ds.save( pt );

pt = ds.get( Point.class, pt.getId() );

Snapshot<Point> ts2 = new Snapshot<Point>();
ts2.setData( pt );

ds.save( ts2 );

ts1 = ds.get( Snapshot.class, ts1.getId() );
ts2 = ds.get( Snapshot.class, ts2.getId() );

Assert.assertEquals( 40.0, ts1.getData().getLatitude() );
Assert.assertEquals( 50.0, ts2.getData().getLatitude() );

Assert.assertEquals( 40.0, ts1.getData().getLongitude() );
Assert.assertEquals( 40.0, ts2.getData().getLongitude() );

两个快照中的点具有与原始点对象相同的 ObjectId,但“ts2”中的点的纬度为 50.0,而“ts1”中的点的纬度为 40.0。ObjectId 值在对象插入数据库时​​分配并且永远不会更改(http://www.mongodb.org/display/DOCS/Object+IDs)。

抱歉,我不确定你的问题到底是什么,但想让你知道我正在做一些非常相似的事情,而且它似乎正在工作。也许尝试将 @Embedded 注释添加到 BookOrderStateHistory 中的“bookOrder”?

祝你好运!

于 2012-08-14T02:28:29.410 回答