Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java MongoDB Morphia-唯一_Java_Mongodb_Playframework 2.0_Morphia - Fatal编程技术网

Java MongoDB Morphia-唯一

Java MongoDB Morphia-唯一,java,mongodb,playframework-2.0,morphia,Java,Mongodb,Playframework 2.0,Morphia,我试图有一个统一的数据库,其中用户名和电子邮件是唯一的 我的用户类如下所示: public class User { @Indexed(unique = true) @Required @MinLength(4) public String username; @Indexed(unique = true) @Required @Email public String email; @Required @Mi

我试图有一个统一的数据库,其中用户名和电子邮件是唯一的

我的用户类如下所示:

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() {
...
我使用了@index(unique=true)注释,但它不起作用。我的数据库中仍有重复项

有没有办法解决这个问题

编辑:

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

我想马上阻止它

糟糕的

try{

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

这里有关于唯一约束的很好的解释,这对您有帮助吗?所以我要做的就是在检查其他错误时,在控制器级别(或bean validate())验证您的数据。这就可以了,但它并没有注释那么酷

编辑

或者,请参阅这篇文章,它清楚地描述了mongodb在唯一索引的默认情况下不会引发错误。如果您不这样说,请尝试配置您的mongodb以引发这些错误,并查看您是否可以使用解决方案:(

编辑2

我还想到,play 2有一个启动全局类,您可以尝试访问数据库并运行索引列命令,如db.things.ensureIndex({email:1},{unique:true});?请参阅

的更多信息如果您尝试索引的列中已经存在重复项,则无法创建索引列

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

db.user.ensureIndex({'username':1},{unique:true})
db.user.ensureIndex({'email':1},{unique:true})
..并检查是否设置了索引:

db.user.getIndexes()

Morphia应该在默认情况下设置,这将在尝试插入违反唯一索引的文档时引发异常。

对于play framework 1.2.6和Morphia 1.2.12,我也遇到了同样的问题

@index(unique=true)注释的解决方案是让morpha重新创建集合。 因此,如果我在mongo中已经有了“Account”集合,并对email列进行了注释,然后重新启动play应用程序,那么Account索引中没有任何更改

如果我删除了帐户收集,morphia将其重新包装,现在电子邮件列是唯一的:

> db.Account.drop()
true
播放后重新启动:(我有一个创建初始帐户的任务…)


现在,在插入一封已经存在的电子邮件后,我得到了一个
MongoException.DuplicateKey
异常。

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

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

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

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

例如,如果您的类名为Author:

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

    m.map(Author.class);

    ds.ensureIndex();

  • 检查mongo db上的索引

    b.Author.getIndexes()

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


这种情况在很多情况下都很明显,如果模式相同,您希望重用实体类,我不明白。当然我可以检查它,但是如果两个用户同时使用相同的用户名注册会怎么样?我需要一些原子性的东西。数据库有自己的内置锁定系统(读、写锁等),所以我相信,如果在数据库级别存在唯一的约束,则不可能同时保存重复数据?也许我错了,但我认为您的意思是这样的。
if(user.not_in_db)ds.save(user)
如果我在db级别没有约束,则会有重复的数据。是的,无论发生什么情况,都要将约束保持在db级别,这样更容易确保在bean级别出现注释等故障时,db至少会阻止数据。使用play 2,您可以创建单独的登录类,该类具有validate()当数据来自模板时要运行的方法。首先查看zentasks项目,该项目可以从play installation samples文件夹中找到。登录类位于play/samples/java/zentasks/app/controllers/Application.java有一个示例如何验证用户名/密码的空情况,扩展它以验证唯一的u另外,如果您不想使用单独的登录类,而是一直使用用户bean(在模板中询问值等),您可以将validate()方法添加到您的用户类中(当表单发送到处理表单提交的相应控制器时,它将被自动调用).多亏了你们两个,这才是我想要的。
Morphia m = ...
Datastore ds = ...

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