TL;DR This post is a first field report for a sketched Spring Data eXist-db implementation. It seems like comparing apples and oranges but on the other hand shows the possibilities of a future development.
During a proof-of-concept, we developed a library to access eXist backed data with the Spring technology stack: Building a Simple eXist Repository on Top of Spring Data.
While the developed library solves all of our requirements we thought it would be a good idea to compare the solution with Spring Data MongoDB to identify the missing parts.
The idea is to migrate a canonical TODO list example backed by MongoDB to eXist: callicoder/spring-boot-mongodb-angular-todo-app
The data model
When working with MongoDB the obvious choice is to use a JSON representation. This can be easily translated into the XML centric eXist world. But what about the other annotations?
@Document(collection="todos")
@JsonIgnoreProperties(value = {"createdAt"}, allowGetters = true)
public class Todo {
@Id
private String id;
@NotBlank
@Size(max=100)
@Indexed(unique=true)
private String title;
private Boolean completed = false;
private Date createdAt = new Date();
The current draft implementation neither supports the Spring Data MongoDB specific @Document
annotation to override the collection name nor the Spring Data @Id
We kind of guess it from the simple name of the @XmlRootElement
and require the id to be explicitly provided via EntityInformation<T, ID>
.
We came up with the following XML backed model class for Todo
:
@XmlRootElement(name = "todo-item")
@XmlType(propOrder = {"title", "completed"})
@XmlAccessorType(XmlAccessType.FIELD)
public class Todo {
@XmlAttribute(name = "id")
private String id;
@NotBlank
@Size(max=100)
private String title;
private Boolean completed = false;
@XmlTransient
private Date createdAt = new Date();
The repository
The is no specific Spring Boot autoconfiguration available nor any convenience configurations like MongoRepositoriesAutoConfiguration
.
Thus requires a manual configuration of the Jaxb2Marschaller
and an EntityInformation
:
@Configuration
static class TodoListRepositoryConfiguration extends ExistTemplateConfiguration {
@Bean
Jaxb2Marshaller jaxb2Marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(Todo.class);
return marshaller;
}
@Bean
XMLEntityInformation<Todo> entityInformation() {
return new TodoListEntityInformation();
}
}
The repository inherits all CRUD methods from ExistXQJRepository.
But currently, it isn't magically enhanced with an aspect conjuring implementations for **find**TodoByTitle
methods or paging/sorting.
import de.datenkollektiv.sandbox.data.exist.ExistTemplate;
import de.datenkollektiv.sandbox.data.exist.ExistXQJRepository;
import de.datenkollektiv.sandbox.data.xml.XMLEntityInformation;
import org.springframework.stereotype.Repository;
@Repository
public class TodoRepository extends ExistXQJRepository<Todo> {
public TodoRepository(
XMLEntityInformation<Todo> entityInformation,
ExistTemplate existTemplate,
Marshaller marshaller,
Unmarshaller unmarshaller) {
super(entityInformation, existTemplate, marshaller, unmarshaller);
}
}
Conclusion
The current "Spring only" implementation covers the basic CRUD operations as well as direct access to XQuery operations. Comparing it with the Spring Boot based MongoDB example reveals the value-add of thoroughly crafted Spring Boot Starters.
A bunch of dependencies has to be added as single dependencies. This could be reduced with an appropriate "set of convenient dependency descriptors" like the ones available from Spring Boot Starter.
There is definitely room for further improvement. But that's another programming day...
If you are a bit adventurous today you can try the example yourself: datenkollektiv/spring-boot-exist-angular-todo-app.
Photo Retro cars in front of yellow garage by Dietmar Becker