【问题标题】:Spring Couchbase CrudRepository type safety?Spring Couchbase CrudRepository 类型安全?
【发布时间】:2014-09-06 06:38:58
【问题描述】:

我正在评估 Spring Data 对 Couchbase 的支持,并且遇到了以下问题。考虑以下伪代码示例,其中我有两个 POJO 类,以及为每个类定义和实例化的存储库:

public class Foo
{
    @Id
    private String  _id;

    @Version
    private Long    _rev;

    // .. Other data and members.
}

public class Bar
{
    @Id
    private String  _id;

    @Version
    private Long    _rev;

    // .. Other data and members.
}


//
// Repositories
//

@Repository
public interface FooRepository extends CrudRepository<Foo, String> {
}

@Repository
public interface BarRepository extends CrudRepository<Bar, String> {
}

两个存储库都使用同一个 Couchbase 存储桶。下一个:

// Create a new Foo object and save it.
Foo f = new Foo( "id_1" );
fooRepository.save( f );

// Now, try fetching a Bar object using the ID of a Foo object (?)
Bar b = barRepository.findOne( "id_1" );

这会导致返回 Bar 对象,但未正确初始化 - 不会引发异常。问题是,为什么在这种情况下没有指示错误?当请求的类型与持久类型不匹配时,引发异常似乎并不难。我错过了什么吗?

FWIW,当我通过管理控制台查看 Couchbase 中的原始文档时,我观察到每个文档都包含一个“_class”属性,大概可用于识别用于表示数据的类,并检测此类不匹配。

【问题讨论】:

  • 您是否在日志中获得了更多信息?如果它无法解析它,则应该向您提出一些问题。 .. 既然这不是一个答案,你能在追踪器上打开一个 DATACOUCH 票吗?
  • @moidaschl - 日志中没有显示任何内容。我确实逐步完成了实现此功能的代码。有趣的是,处理决定使用什么类型的代码根本不处理不匹配。如果您有兴趣,请参阅 MappingCouchbaseConverter.read()/DefaultTypeMapper.readType()。我会为此提交一张票。

标签: java spring spring-data couchbase spring-data-couchbase


【解决方案1】:

这里的问题是文档(JSON 序列化实体)与其他实体在同一个存储桶上的 id(@Id 字段)相关联,这会产生一种歧义,将Entity1 保存为 id 1 , 将用 id 1 覆盖 Entity2

应用程序端的解决方案是存储具有不同键的实体,在 Entity1 的情况下,ID 1 类似于:1-Entity1 作为键。

也许您可以使用与此类似的方法来解决问题:

public Entity1 {

    private static final String ENTITY_NAME = "ENTITY1";

    @Id
    private String key;

    public void setKey(String key) {
        this.key = key;
    }

    public String getKey(String key) {
        return this.key;
    }

    public void setId(String id) {
        this.key = ENTITY_NAME + ":" + id;
    }

    public String getId() {
        if (null == this.key) 
            return null;
        return this.key.substring(ENTITY_NAME.length()+1);
    }

}

【讨论】:

  • 毫无疑问,将不同类型的对象存储在同一个桶中会产生歧义。我的问题是,当我要求 CrudRepository 实例返回 Bar 对象时,为什么 CouchBase Crud 存储库包没有将场景检测为错误,给定一个 Foo 对象的 ID?在我看来,验证存储的类型与请求的类型相匹配很有意义。
  • 我明白了。我所指的是这里指出的问题的根本原因。如果您保存,在您的情况下FooBar,使用相同的@Id,最后一个将覆盖第一个,我的理解不应该发生(它不直观)。考虑到一个不应该覆盖另一个实体类的检查在读取时没有意义。
猜你喜欢
  • 2014-12-30
  • 2020-02-12
  • 2020-03-20
  • 2015-06-13
  • 2020-07-19
  • 1970-01-01
  • 2017-09-03
  • 2018-12-27
  • 2014-06-24
相关资源
最近更新 更多