Mapping domain objects with MongoDB

Let's begin by mapping our Event.java file so that each of the domain objects are saved as a document in our MongoDB database. This can be done by performing the following steps: 

  1. With a document database, domain object mapping is a little different, but the same ORM concepts hold true. Let's begin with the Event JPA implementation, then take a look how we can transform our Entity to document mapping:
        //src/main/java/com/packtpub/springsecurity/domain/Event.java

...
import javax.persistence.*;
@Entity
@Table(name = "events")
public class Event implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String summary;
private String description;
private Calendar when;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="owner", referencedColumnName="id")
private CalendarUser owner;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="attendee", referencedColumnName="id")
private CalendarUser attendee;
  1. In Entity-based JPA mapping, we needed to use six different annotations to create the required mapping. Now, with document-based MongoDB mapping, we need to change all the previous mapping annotations. Here is a fully refactored example of our Event.java file:
        //src/main/java/com/packtpub/springsecurity/domain/Event.java

import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.domain.Persistable;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
...
@Document(collection="events")
public class Event implements Persistable<Integer>, Serializable{
@Id
private Integer id;
private String summary;
private String description;
private Calendar when;
@DBRef
private CalendarUser owner;
@DBRef
private CalendarUser attendee;
@PersistenceConstructor
public Event(Integer id,
String summary,
String description,
Calendar when,
CalendarUser owner,
CalendarUser attendee) {
...
}

In the preceding code, we can see a following few notable changes:

  1. First, we declare the class to be of type @o.s.d.mongodb.core.mapping.Document, and provide a collection name for these documents.
  2. Next, the Event class must implement the o.s.d.domain.Persistable interface, providing the primary key type (Integer) for our document.
  3. Now, we change the annotation for our domain ID to @o.s.d.annotation.Id, to define the domain primary key.
  4. Previously, we had to map our owner and attendee CalendarUser object to two different mapping annotations.
  5. Now, we only have to define the two types to be of type @o.s.d.mongodb.core.mapping.DBRef, and allow Spring Data to take care of the underlying references.
  6. The final annotation we have to add defines a specific constructor to be used for new documents to be added to our document, by using the @o.s.d.annotation.PersistenceConstructor annotation.
  7. Now that we have reviewed the changes needed to refactor from JPA to MongoDB, let's refactor the other domain object starting with the Role.java file, as follows:
        //src/main/java/com/packtpub/springsecurity/domain/Role.java

...
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.domain.Persistable;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection="role")
public class Role implements Persistable<Integer>, Serializable {
@Id
private Integer id;
private String name;
public Role(){}
@PersistenceConstructor
public Role(Integer id, String name) {
this.id = id;
this.name = name;
}
  1. The final domain object that we need to refactor is our CalendarUser.java file. After all, this is the most complex domain object we have in this application:
        //src/main/java/com/packtpub/springsecurity/domain/CalendarUser.java

...
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.domain.Persistable;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection="calendar_users")
public class CalendarUser implements Persistable<Integer>,
Serializable {
@Id
private Integer id;
private String firstName;
private String lastName;
private String email;
private String password;
@DBRef(lazy = false)
private Set<Role> roles = new HashSet<>(5);
public CalendarUser() {}
@PersistenceConstructor
public CalendarUser(Integer id,String email, String password,
String firstName,String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
}

As you can see, the effort to refactor our domain objects from JPA to MongoDB is fairly simple, and requires less annotation configuration than the JPA configuration.