Nikos Kitmeridis
Software Developer @ AMD Telecom
POJOs Various forms of storage
Sub-projects exist for different backend technologies
Define your model
Define your model
Example
@Document(collection = "account")
@TypeAlias("Account")
@CompoundIndexes({
@CompoundIndex(name = "company_info", def = "{'industry': 1, 'type': 1}")
})
public class Account {
@Id
private String id;
@Indexed(name = "organizationName_1", unique = true)
private String organizationName;
private String industry;
private OrganizationType type;
private Long noOfUsers;
@Transient
private Set<User> users;
@Indexed(name = "createdAt_1")
private Date createdAt;
...
}
// Central repository marker interface.
public interface Repository<T, ID> {}
// Interface for generic CRUD operations on a repository for a specific type.
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S entity);
<S extends T> Iterable<S> save(Iterable<S> entities);
T findOne(ID id);
boolean exists(ID id);
Iterable<T> findAll();
Iterable<T> findAll(Iterable<ID> ids);
long count();
void delete(ID id);
void delete(T entity);
void delete(Iterable<? extends T> entities);
void deleteAll();
}
// Extension of CrudRepository to provide additional methods to retrieve entities using the pagination and
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
public interface UserRepository extends PagingAndSortingRepository<User, String> {
User findByUsername(String Username); // No <Op> for Equals
User findByLastnameOrderByFirstname(String lastname);
User findByBirthdateBetween(Date date1, Date date2);
@Query(value = "{'birthdate': {$gte: ?0, $lte: ?1}}")
Collection<Account> findByBirthDateBetween(Date date1, Date date2);
}
3 Steps to implement Custom Repositories
interface UserRepositoryCustom {
public void someCustomMethod(User user);
}
interface UserRepository extends CrudRepository<User, Long>, UserRepositoryCustom {
// Declare query methods here
}
class UserRepositoryImpl implements UserRepositoryCustom {
public void someCustomMethod(User user) {
// Your custom implementation
}
}
The MongoTemplate class is the central class of the Spring’s MongoDB support providing a rich feature set to interact with the database.
public interface MongoOperations {
String getCollectionName(Class<?> entityClass);
...
CommandResult executeCommand(String jsonCommand);
...
void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch);
...
<T> DBCollection createCollection(Class<T> entityClass);
...
<T> GroupByResults<T> group(Criteria criteria, String inputCollectionName, GroupBy groupBy, Class<T> entityClass);
...
<O> AggregationResults<O> aggregate(TypedAggregation<?> aggregation, String collectionName, Class<O> outputType);
...
<T> MapReduceResults<T> mapReduce(String inputCollectionName, String mapFunction, String reduceFunction, Class<T> entityClass);
...
<T> List<T> find(Query query, Class<T> entityClass);
...
<T> T findAndModify(Query query, Update update, Class<T> entityClass);
...
void insert(Object objectToSave, String collectionName);
...
WriteResult upsert(Query query, Update update, Class<?> entityClass, String collectionName);
...
WriteResult updateFirst(Query query, Update update, Class<?> entityClass);
...
WriteResult updateMulti(Query query, Update update, Class<?> entityClass);
...
WriteResult remove(Object object);
...
}
Initial Dataset
Expected DataSet
"user": [
{
"_id": "u1",
"userName": "allan123",
"firstName": "Allan",
"lastName": "Connolly",
"email": "OLDEMAIL@example.com"
}
]
"user": [
{
"_id": "u1",
"userName": "allan123",
"firstName": "Allan",
"lastName": "Connolly",
"email": "NEWEMAIL@example1.com"
}
]
Unit Test's executed query
db.user.update(
{ "_id": "u1" },
{ $set: { "email": "NEWEMAIL@example.com" } },
{ upsert: true }
)
@UsingDataSet
@ShouldMatchDataSet
@IgnorePropertyValue
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfiguration.class)
@CustomComparisonStrategy(comparisonStrategy = MongoFlexibleComparisonStrategy.class)
public class AccountRepositoryTester {
@Rule
public MongoDbRule mongoDbRule = newMongoDbRule().defaultSpringMongoDb("springdata-poc-test");
@Autowired
private ApplicationContext applicationContext;
@Autowired
private AccountRepository accountRepository;
@Test
@UsingDataSet(locations = "Initial-AccountDataSet.json")
@ShouldMatchDataSet(location = "Expected-AccountDataSet.json")
@IgnorePropertyValue(properties = {"account.updatedAt"})
public void test_UpdateAccountsField_whenAccountExistsAndFieldExists_updatesAccount() {
accountRepository.updateAccountsField("c1", "industry", "Financial");
}
}
Introduction to Spring Data JPA and Spring Data MongoDB
(by Nik Trevallyn Jones, many slides of the current presentation are based on this video)
https://www.youtube.com/watch?v=P05GlyrIz0o
__________________________________________________________
Spring Data MongoDb Documentation
http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/
__________________________________________________________
NoSQLUnit Source code & Documentation
https://github.com/lordofthejars/nosql-unit
___________________________________________________________________________________
Simple POC on Spring data Mongodb & NoSQLUnit