【问题标题】:MongoDB Morphia - UniqueMongoDB Morphia - 独特的
【发布时间】:2012-08-02 11:21:51
【问题描述】:

我正在尝试拥有一个一致的数据库,其中用户名和电子邮件是唯一的。

http://www.mongodb.org/display/DOCS/Indexes#Indexes-unique%3Atrue

http://code.google.com/p/morphia/wiki/EntityAnnotation

我的用户类如下所示:

public class User {
    @Indexed(unique = true)
    @Required
    @MinLength(4)
    public String username;

    @Indexed(unique = true)
    @Required
    @Email
    public String email;

    @Required
    @MinLength(6)
    public String password;

    @Valid
    public Profile profile;

    public User() {
...

我使用了@Indexed(unique=true) 注释,但它不起作用。我的数据库中仍有重复项。

有什么办法可以解决这个问题吗?

编辑:

我读到了 ensureIndexes 但这似乎是一种错误的方法,我不想上传重复的数据,只是想看看它真的是重复的。

我想马上屏蔽它。

类似的东西

try{

ds.save(user);
}
catch(UniqueException e){
...
}

【问题讨论】:

    标签: java mongodb playframework-2.0 morphia


    【解决方案1】:

    如果您尝试索引的列中已有重复项,则无法创建 unique index

    我会尝试从mongo shell 运行您的ensureIndex 命令:

    db.user.ensureIndex({'username':1},{unique:true})
    db.user.ensureIndex({'email':1},{unique:true})
    

    .. 并检查索引是否设置:

    db.user.getIndexes()
    

    Morphia 应该默认设置WriteConcern.SAFE,这会在尝试插入违反唯一索引的文档时引发异常。

    【讨论】:

    • 谢谢你们,这就是我要找的。​​span>
    【解决方案2】:

    这里有关于唯一约束的很好的解释 Unique constraint with JPA and Bean Validation ,这对你有帮助吗?所以我要做的只是在检查其他错误时在控制器级别(或 bean validate())验证您的数据。这样就可以完成这项工作,但它没有注释那么酷。

    编辑

    或者看到这篇文章Inserting data to MongoDB - no error, no insert,它清楚地描述了mongodb默认情况下不会引发错误,如果你不告诉它,尝试配置你的mongodb来抛出这些错误,看看你是否可以工作有解决方案:(

    编辑 2

    我还想到 play 2 有一个启动全局类,您可以在其中尝试访问数据库并运行索引列命令,例如 db.things.ensureIndex({email:1},{unique:true} ); ??更多信息请访问http://www.playframework.org/documentation/2.0/JavaGlobal

    【讨论】:

    • 嗯,我不明白。当然我可以检查它,但是如果两个用户同时使用相同的用户名注册怎么办?我需要一些原子的东西。
    • 数据库有自己的内置锁定系统(读、写锁等),所以我相信如果在数据库级别存在独特的约束 - 同时保存重复数据是不可能的?
    • 也许我错了,但我以为你的意思是这样的。 if(user.not_in_db) ds.save(user); 如果我在 db 级别没有约束,就会有重复的数据。
    • 是的,无论如何都将约束保持在数据库级别,如果 bean 级别的某些内容(如注释)失败,则更容易确保您的数据库至少会阻止数据。使用 play 2,您可以创建单独的 Login 类,该类具有 validate() 方法,当数据来自模板时运行。首先查看 zentasks 项目,该项目可以从您的 play 安装示例文件夹中找到。登录类我的意思是它位于 play/samples/java/zentasks/app/controllers/Application.java 有示例如何验证用户名/密码的空情况,扩展它以验证唯一用户。
    • 另外,如果您不想一直使用单独的 Login 类而是 User bean(在询问值等时在模板中),您可以将该 validate() 方法添加到您的 User 类中(它将当表单发送到处理表单提交的相应控制器时被播放自动调用)。
    【解决方案3】:

    我有同样的问题,游戏框架 1.2.6 和 morphia 1.2.12。

    @Indexed(unique = true) 注释的解决方案是让morpha 重新创建集合。 因此,如果我已经在 mongo 中拥有“帐户”集合,并注释了电子邮件列,并重新启动了 play 应用程序,那么帐户索引中没有任何变化。

    如果我删除了 Account ollection,morphia 会重新创建它,现在电子邮件列是唯一的:

    > db.Account.drop()
    true
    

    播放重启后:(我有一个创建初始帐户的工作......)

    > db.Account.getIndexes()
    [
            {
                    "v" : 1,
                    "key" : {
                            "_id" : 1
                    },
                    "ns" : "something.Account",
                    "name" : "_id_"
            },
            {
                    "v" : 1,
                    "key" : {
                            "email" : 1
                    },
                    "unique" : true,
                    "ns" : "something.Account",
                    "name" : "email_1"
            }
    ]
    

    现在,在插入现有电子邮件后,我收到 MongoException.DuplicateKey 异常。

    【讨论】:

      【解决方案4】:

      要创建索引,需要调用Datastore.ensureIndexes() 方法将索引应用到MongoDB。在您向 Morphia 注册实体后,应调用该方法。然后它将同步创建您的索引。这可能应该在您每次启动应用程序时完成。

      Morphia m = ...
      Datastore ds = ...
      
      m.map(Product.class);
      ds.ensureIndexes(); //creates all defined with @Indexed
      

      【讨论】:

        【解决方案5】:

        Morphia 将使用类名或 @Entity 注释值为集合创建索引。

        例如,如果您的班级名称是作者:

        • 请确保您的实体类中有@Indexed 注解,并且您已完成以下两个步骤:

          m.map(Author.class);

          ds.ensureIndexes();

        • 在 mongo db 上检查索引

          b.Author.getIndexes()

        我添加这个答案,以强调您不能使用自定义集合名称创建索引(实体类是作者,但您的集合名称不同)

        这种情况在很多情况下都很明显,如果架构相同,您希望重用实体类

        【讨论】:

          猜你喜欢
          • 2013-09-10
          • 1970-01-01
          • 1970-01-01
          • 2011-07-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多