Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Enhance support for linking documents. #3647

Closed
wants to merge 6 commits into from
Closed

Conversation

christophstrobl
Copy link
Member

Using @DocumentReference offers an alternative way of linking entities in MongoDB. While the goal is the same as when using @DBRef, the store representation is different. Document references, do not follow a specific format. They can be literally anything, a single value, an entire document, basically everything that can be stored in MongoDB.
By default, the mapping layer will use the referenced entities id value for storage and retrieval, like in the sample below.

@Document
public class Account {

  @Id
  private String id;
  private Float total;
}

@Document
public class Person {

  @Id
  private String id;

  @DocumentReference
  private List<Account> accounts;
}
Account account = ...

tempate.insert(account);

template.update(Person.class)
  .matching(where("id").is("6c78727"))
  .apply(new Update().push("accounts").value(account)) 
  .first();
{
  "_id" : "6c78727",
  "accounts" : [ "6509b9e", "d3e21be" ] 
}

The sample above uses an _id based fetch query ({ '_id' : ?#{#target} }) for data retrieval and resolves linked entities eagerly.

@DocumentReference(lookup=...) allows to define custom queries that are independent from the _id field and therefore offer a flexible way of defining links between entities as demonstrated in the sample below, where the Publisher of a book is referenced by its acronym instead of the internal id.

@Document
public class Book {

  @Id
  private ObjectId id;
  private String title;
  private List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }")
  private Publisher publisher;
}

@Document
public class Publisher {

  @Id
  private ObjectId id;
  private String acronym;
  private String name;

  @DocumentReference(lazy = true)
  private List<Book> books;

}
{
  "_id" : "9a48e32",
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher_ac" : "DR"
}

The above snipped shows the reading side of things when working with custom linked objects. To make the writing part aware of the modified document pointer a custom converter, capable of the transformation into a DocumentPointer, like the one below, needs to be registered.

@WritingConverter
class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {

	@Override
	public DocumentPointer<String> convert(Publisher source) {
		return () -> source.getAcronym();
	}
}

christophstrobl and others added 6 commits May 20, 2021 11:10
Add initial support for an alternative to the existing DBRef scenario.
The enhancement allows to store and retrieve linked entites via their id or a customizable lookup query.
…query.

Simplify usage by computing the pointer from the lookup.
Update the reference documentation, add JavaDoc and refine API.
Rename ReferenceReader to ReferenceLookupDelegate.
Rename LazyLoadingProxyGenerator to LazyLoadingProxyFactory.
Rename DefaultReferenceLoader to MongoDatabaseFactoryReferenceLoader.

Reduce scope of LookupFunction and move it to ReferenceLookupDelegate.

Extract some checks into methods to reflect the underlying concepts. Simplify code, convert variables to constants where possible.
Also allow direct usage of (at)Reference from data commons to define associations.
@christophstrobl christophstrobl marked this pull request as ready for review May 20, 2021 10:30
mp911de pushed a commit that referenced this pull request May 21, 2021
Add initial support for an alternative to the existing DBRef scenario.
The enhancement allows to store and retrieve linked entites via their id or a customizable lookup query.

Original pull request: #3647.
Closes #3602.
mp911de added a commit that referenced this pull request May 21, 2021
Original pull request: #3647.
Closes #3602.
mp911de pushed a commit that referenced this pull request May 21, 2021
…query.

Simplify usage by computing the pointer from the lookup.
Update the reference documentation, add JavaDoc and refine API.

Original pull request: #3647.
Closes #3602.
mp911de added a commit that referenced this pull request May 21, 2021
Rename ReferenceReader to ReferenceLookupDelegate.
Rename LazyLoadingProxyGenerator to LazyLoadingProxyFactory.
Rename DefaultReferenceLoader to MongoDatabaseFactoryReferenceLoader.

Reduce scope of LookupFunction and move it to ReferenceLookupDelegate.

Extract some checks into methods to reflect the underlying concepts. Simplify code, convert variables to constants where possible.

Original pull request: #3647.
Closes #3602.
mp911de pushed a commit that referenced this pull request May 21, 2021
Also allow direct usage of (at)Reference from data commons to define associations.

Original pull request: #3647.
Closes #3602.
mp911de added a commit that referenced this pull request May 21, 2021
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.
mp911de added a commit that referenced this pull request May 21, 2021
@mp911de mp911de added the type: enhancement A general enhancement label May 21, 2021
@mp911de mp911de added this to the 3.3 M1 (2021.1.0) milestone May 21, 2021
@mp911de
Copy link
Member

mp911de commented May 21, 2021

That's merged and polished now.

@yihtserns
Copy link

yihtserns commented Jan 13, 2024

#3602

(Manually link because nobody linked these two related things)

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants