我是弹簧数据和mongo的新手,所以可能是我的pbm真的很容易......
我有一个简单的文档User
,其ID为object ID
,登录String
的注释为@Indexed(unique = true)
。
使用MongoOperations : mongoOperations.save(user);
我创建了一个简单的单元测试来检查重复登录是否被拒绝。它似乎工作正常。
之后,我添加了另一项测试来检查是否找不到未知用户...
对我来说非常奇怪的是因为这个新测试在第一个测试之前执行,第一个测试失败:2个具有相同登录的用户被插入到DB中。
如果我直接检查mongo客户端,我可以看到存储了2个具有相同登录名的对象。
db.user.find({})
{
"_id" : ObjectId("5904f59c5ea29c288c593280"),
"_class" : "com.test.User", "login" : "toto"
}
{
"_id" : ObjectId("5904f59c5ea29c288c593282"),
"_class" : "com.test.User", "login" : "toto"
}
对此有任何解释吗?
我正在使用:
请在下面找到我的代码的一部分(我希望我没有错过任何重要的事情)。
application.properties
spring.data.mongodb.uri=mongodb://localhost/mydb
文档用户
@Document
public class User {
@Id
private ObjectId id;
@Indexed(unique = true)
public String login;
private String pass;
public User() {
}
public User(String login, String pass) {
this.login = login;
this.pass = pass;
}
public ObjectId getId() {
return id;
}
}
我的Junit测试:
@EnableAutoConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = { UserController.class })
@ComponentScan("com.test")
public class TestUserController {
@Autowired
private DbInitialisatioController dbInitController;
@Autowired
private UserController controller;
@Autowired
MongoTemplate mongoTemplate;
@Before
public void setup() {
mongoTemplate.getDb().dropDatabase();
// Should not be usefull, but without that call test is not successfull
dbInitController.init();
}
@Test
public void testFindUnknownUser() {
Assert.assertNull("User bob should be null as does not exists", controller.findByLogin("bob"));
}
@Test
public void testCreateUser_ErrorSavingTwice() throws MyException {
User user = new User("toto", "pass");
controller.createUser(user);
try {
controller.createUser(user);
Assert.fail("User must not be saved twice");
} catch (MyException e) {
Assert.assertEquals(ErrorCode.INTERNAL_ERROR, e.getErrorCode());
}
}
}
"控制器"它的作用是执行对DB的访问。
@Component
public class UserController {
final static Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
MongoOperations mongoOperations;
@Autowired
ProfilController profilController;
public User findByLogin(String login) {
Query query = new Query();
query.addCriteria(Criteria.where("login").is(login));
return mongoOperations.findOne(query, User.class);
}
public void createUser(User user) throws MyException {
if (user.getId() != null) {
throw new MyException(ErrorCode.INTERNAL_ERROR, "could not saveNewUser for existing user");
}
logger.info("Creating user {}", user);
try {
mongoOperations.save(user);
logger.info("Created {}", user);
} catch (org.springframework.dao.DuplicateKeyException e) {
throw new MyException(ErrorCode.LOGIN_ALREADY_EXITS, user.login);
}
}
// ... some other methods
}
此类不应退出,但如果没有,则测试失败
@Component
public class DbInitialisatioController {
final static Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
MongoOperations mongoOperations;
@Autowired
UserController userController;
/**
* Note I don't understand why I need to create indexes here. I was expecting that Indexed annotation in User and Profil would do the same...
*/
public void init() {
logger.info("Initializing DB");
mongoOperations.indexOps(User.class).ensureIndex(new Index().on("login", Direction.ASC).unique());
mongoOperations.indexOps(Profile.class).ensureIndex(new Index().on("login", Direction.ASC).unique());
}
}