Skip to content

Commit

Permalink
Polishing.
Browse files Browse the repository at this point in the history
Reduce dependencies in tests by using NoOpDbRefResolver.
Add since tags.

Tweak documentation. Extract entity references into own documentation fragment.

Original pull request: #3647.
Closes #3602.
  • Loading branch information
mp911de committed May 21, 2021
1 parent e96ef8e commit 5ab75eb
Show file tree
Hide file tree
Showing 23 changed files with 680 additions and 654 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,6 @@ private void readAssociation(Association<MongoPersistentProperty> association, P

DBRef dbref = value instanceof DBRef ? (DBRef) value : null;

// TODO: accessor.setProperty(property, dbRefResolver.resolveReference(property, value, referenceReader,
// context::convert));
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, dbref, callback, handler));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
/**
* {@link ReferenceLoader} implementation using a {@link MongoDatabaseFactory} to obtain raw {@link Document documents}
* for linked entities via a {@link ReferenceLoader.DocumentReferenceQuery}.
*
*
* @author Christoph Strobl
* @since 3.3
*/
public class MongoDatabaseFactoryReferenceLoader implements ReferenceLoader {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
/**
* The {@link ReferenceLoader} obtains raw {@link Document documents} for linked entities via a
* {@link ReferenceLoader.DocumentReferenceQuery}.
*
*
* @author Christoph Strobl
* @since 3.3
*/
Expand Down Expand Up @@ -79,7 +79,6 @@ default Bson getSort() {
return new Document();
}

// TODO: Move apply method into something else that holds the collection and knows about single item/multi-item
default Iterable<Document> apply(MongoCollection<Document> collection) {
return restoreOrder(collection.find(getQuery()).sort(getSort()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 3.3
*/
public final class ReferenceLookupDelegate {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

/**
* A custom pointer to a linked document to be used along with {@link DocumentReference} for storing the linkage value.
*
*
* @author Christoph Strobl
* @since 3.3
*/
@FunctionalInterface
public interface DocumentPointer<T> {
Expand All @@ -27,7 +28,7 @@ public interface DocumentPointer<T> {
* The actual pointer value. This can be any simple type, like a {@link String} or {@link org.bson.types.ObjectId} or
* a {@link org.bson.Document} holding more information like the target collection, multiple fields forming the key,
* etc.
*
*
* @return the value stored in MongoDB and used for constructing the {@link DocumentReference#lookup() lookup query}.
*/
T getPointer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@
import java.lang.annotation.Target;

import org.springframework.data.annotation.Reference;
import org.springframework.data.mongodb.MongoDatabaseFactory;

/**
* A {@link DocumentReference} offers an alternative way of linking entities in MongoDB. While the goal is the same as
* when using {@link DBRef}, the store representation is different and can be literally anything, a single value, an
* entire {@link org.bson.Document}, basically everything that can be stored in MongoDB. By default, the mapping layer
* will use the referenced entities {@literal id} value for storage and retrieval.
*
* A {@link DocumentReference} allows referencing entities in MongoDB using a flexible schema. While the goal is the
* same as when using {@link DBRef}, the store representation is different. The reference can be anything, a single
* value, an entire {@link org.bson.Document}, basically everything that can be stored in MongoDB. By default, the
* mapping layer will use the referenced entities {@literal id} value for storage and retrieval.
*
* <pre class="code">
* public class Account {
* private String id;
Expand All @@ -40,7 +41,7 @@
* &#64;DocumentReference
* private List&lt;Account&gt; accounts;
* }
*
*
* Account account = ...
*
* mongoTemplate.insert(account);
Expand All @@ -50,43 +51,41 @@
* .apply(new Update().push("accounts").value(account))
* .first();
* </pre>
*
* {@link #lookup()} allows to define custom queries that are independent from the {@literal id} field and in
* combination with {@link org.springframework.data.convert.WritingConverter writing converters} offer a flexible way of
* defining links between entities.
*
*
* {@link #lookup()} allows defining a query filter that is independent from the {@literal _id} field and in combination
* with {@link org.springframework.data.convert.WritingConverter writing converters} offers a flexible way of defining
* references between entities.
*
* <pre class="code">
* public class Book {
* private ObjectId id;
* private String title;
* private ObjectId id;
* private String title;
*
* &#64;Field("publisher_ac")
* &#64;DocumentReference(lookup = "{ 'acronym' : ?#{#target} }")
* private Publisher publisher;
* &#64;Field("publisher_ac") &#64;DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") private Publisher publisher;
* }
*
* public class Publisher {
*
* private ObjectId id;
* private String acronym;
* private String name;
* private ObjectId id;
* private String acronym;
* private String name;
*
* &#64;DocumentReference(lazy = true)
* private List&lt;Book&gt; books;
* &#64;DocumentReference(lazy = true) private List&lt;Book&gt; books;
* }
*
* &#64;WritingConverter
* public class PublisherReferenceConverter implements Converter&lt;Publisher, DocumentPointer&lt;String&gt;&gt; {
*
* public DocumentPointer&lt;String&gt; convert(Publisher source) {
* public DocumentPointer&lt;String&gt; convert(Publisher source) {
* return () -> source.getAcronym();
* }
* }
* }
* </pre>
*
* @author Christoph Strobl
* @since 3.3
* @see <a href="https://docs.mongodb.com/manual/reference/database-references/#std-label-document-references">MongoDB Reference Documentation</a>
* @see <a href="https://docs.mongodb.com/manual/reference/database-references/#std-label-document-references">MongoDB
* Reference Documentation</a>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
Expand All @@ -95,31 +94,32 @@
public @interface DocumentReference {

/**
* The database the linked entity resides in.
* The database the referenced entity resides in. Uses the default database provided by
* {@link org.springframework.data.mongodb.MongoDatabaseFactory} if empty.
*
* @return empty String by default. Uses the default database provided buy the {@link org.springframework.data.mongodb.MongoDatabaseFactory}.
* @see MongoDatabaseFactory#getMongoDatabase()
* @see MongoDatabaseFactory#getMongoDatabase(String)
*/
String db() default "";

/**
* The database the linked entity resides in.
* The collection the referenced entity resides in. Defaults to the collection of the referenced entity type.
*
* @return empty String by default. Uses the property type for collection resolution.
* @see MongoPersistentEntity#getCollection()
*/
String collection() default "";

/**
* The single document lookup query. In case of an {@link java.util.Collection} or {@link java.util.Map} property
* the individual lookups are combined via an `$or` operator.
* The single document lookup query. In case of an {@link java.util.Collection} or {@link java.util.Map} property the
* individual lookups are combined via an {@code $or} operator. {@code target} points to the source value (or
* document) stored at the reference property. Properties of {@code target} can be used to define the reference query.
*
* @return an {@literal _id} based lookup.
*/
String lookup() default "{ '_id' : ?#{#target} }";

/**
* A specific sort.
*
* @return empty String by default.
*/
String sort() default "";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import org.springframework.data.mongodb.core.MongoExceptionTranslator;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
Expand All @@ -37,12 +38,15 @@
import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoDatabase;
import com.mongodb.session.ServerSession;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;

/**
* @author Christoph Strobl
*/
@ExtendWith(MockitoExtension.class)
public class MongoTransactionManagerUnitTests {
@MockitoSettings(strictness = Strictness.LENIENT)
class MongoTransactionManagerUnitTests {

@Mock ClientSession session;
@Mock ClientSession session2;
Expand All @@ -53,23 +57,25 @@ public class MongoTransactionManagerUnitTests {
@Mock MongoDatabase db2;

@BeforeEach
public void setUp() {
void setUp() {

when(dbFactory.getSession(any())).thenReturn(session, session2);
when(dbFactory.getExceptionTranslator()).thenReturn(new MongoExceptionTranslator());
when(dbFactory2.getExceptionTranslator()).thenReturn(new MongoExceptionTranslator());
when(dbFactory.withSession(session)).thenReturn(dbFactory);
when(dbFactory.getMongoDatabase()).thenReturn(db);
when(session.getServerSession()).thenReturn(serverSession);
}

@AfterEach
public void verifyTransactionSynchronizationManager() {
void verifyTransactionSynchronizationManager() {

assertThat(TransactionSynchronizationManager.getResourceMap().isEmpty()).isTrue();
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse();
}

@Test // DATAMONGO-1920
public void triggerCommitCorrectly() {
void triggerCommitCorrectly() {

MongoTransactionManager txManager = new MongoTransactionManager(dbFactory);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition());
Expand All @@ -91,7 +97,7 @@ public void triggerCommitCorrectly() {
}

@Test // DATAMONGO-1920
public void participateInOnGoingTransactionWithCommit() {
void participateInOnGoingTransactionWithCommit() {

MongoTransactionManager txManager = new MongoTransactionManager(dbFactory);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition());
Expand Down Expand Up @@ -126,7 +132,7 @@ protected void doInTransactionWithoutResult(TransactionStatus status) {
}

@Test // DATAMONGO-1920
public void participateInOnGoingTransactionWithRollbackOnly() {
void participateInOnGoingTransactionWithRollbackOnly() {

MongoTransactionManager txManager = new MongoTransactionManager(dbFactory);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition());
Expand Down Expand Up @@ -163,7 +169,7 @@ protected void doInTransactionWithoutResult(TransactionStatus status) {
}

@Test // DATAMONGO-1920
public void triggerRollbackCorrectly() {
void triggerRollbackCorrectly() {

MongoTransactionManager txManager = new MongoTransactionManager(dbFactory);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition());
Expand All @@ -185,7 +191,7 @@ public void triggerRollbackCorrectly() {
}

@Test // DATAMONGO-1920
public void suspendTransactionWhilePropagationNotSupported() {
void suspendTransactionWhilePropagationNotSupported() {

MongoTransactionManager txManager = new MongoTransactionManager(dbFactory);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition());
Expand Down Expand Up @@ -228,7 +234,7 @@ protected void doInTransactionWithoutResult(TransactionStatus status) {
}

@Test // DATAMONGO-1920
public void suspendTransactionWhilePropagationRequiresNew() {
void suspendTransactionWhilePropagationRequiresNew() {

when(dbFactory.withSession(session2)).thenReturn(dbFactory2);
when(dbFactory2.getMongoDatabase()).thenReturn(db2);
Expand Down Expand Up @@ -277,7 +283,7 @@ protected void doInTransactionWithoutResult(TransactionStatus status) {
}

@Test // DATAMONGO-1920
public void readonlyShouldInitiateASessionStartAndCommitTransaction() {
void readonlyShouldInitiateASessionStartAndCommitTransaction() {

MongoTransactionManager txManager = new MongoTransactionManager(dbFactory);

Expand All @@ -303,7 +309,7 @@ public void readonlyShouldInitiateASessionStartAndCommitTransaction() {
}

@Test // DATAMONGO-1920
public void readonlyShouldInitiateASessionStartAndRollbackTransaction() {
void readonlyShouldInitiateASessionStartAndRollbackTransaction() {

MongoTransactionManager txManager = new MongoTransactionManager(dbFactory);

Expand Down
Loading

0 comments on commit 5ab75eb

Please # to comment.