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()
这种情况在很多情况下都很明显,如果模式相同,您希望重用实体类,我不明白。当然我可以检查它,但是如果两个用户同时使用相同的用户名注册会怎么样?我需要一些原子性的东西。数据库有自己的内置锁定系统(读、写锁等),所以我相信,如果在数据库级别存在唯一的约束,则不可能同时保存重复数据?也许我错了,但我认为您的意思是这样的。
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