- Spring Security(Third Edition)
- Mick Knutson Robert Winch Peter Mularien
- 552字
- 2025-04-04 17:54:29
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:
- 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;
…
- 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:
- First, we declare the class to be of type @o.s.d.mongodb.core.mapping.Document, and provide a collection name for these documents.
- Next, the Event class must implement the o.s.d.domain.Persistable interface, providing the primary key type (Integer) for our document.
- Now, we change the annotation for our domain ID to @o.s.d.annotation.Id, to define the domain primary key.
- Previously, we had to map our owner and attendee CalendarUser object to two different mapping annotations.
- 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.
- 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.
- 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;
}
- 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.