5

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

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){
...
}
4

5 回答 5

5

如果您尝试索引的列中已经存在重复项,则无法创建唯一索引。

我会尝试ensureIndexmongoshell 运行你的命令:

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

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

db.user.getIndexes()

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

于 2012-08-05T00:11:15.137 回答
1

这里有关于唯一约束的很好的解释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上查看更多信息

于 2012-08-04T22:19:10.543 回答
0

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

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

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

> 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例外。

于 2013-09-08T19:35:23.540 回答
0

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

Morphia m = ...
Datastore ds = ...

m.map(Product.class);
ds.ensureIndexes(); //creates all defined with @Indexed
于 2014-07-06T21:26:16.527 回答
0

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

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

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

    m.map(Author.class);

    ds.ensureIndexes();

  • 检查 mongo db 上的索引

    b.Author.getIndexes()

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

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

于 2015-10-20T05:43:24.937 回答