Spring Data Sophora 3

Advanced Tips and Tricks

This part of the reference documentation will show some additional configurations and possibilities to customize the process of mapping your Sophora documents to your Java models.

This part of the reference documentation will show some additional configurations and possibilities to customize the process of mapping your Sophora documents to your Java models.

Repository Options

Repositories (classes that inherit from SophoraDocumentRepository) can be annotated with @RepositoryOptions. The annotation contains fields to further configure the behavior of the repository. The following settings can be done:

SettingPossible ValuesDefault ValueDescription
liveWorkspacetrue, falsefalseIf true, this repository returns the published documents instead of the working versions.
solrCorethe name of any of your Solr cores"default", or "default-live" if liveWorkspace is trueThe Solr core to use when querying for documents.
overridingComponentstrue, falsefalseWhen set to true, enables overriding of properties and child nodes in referenced documents with properties and child nodes of the referencing node.

Custom Entity Class Resolver

Sometimes your model class hierarchy is not linear e.g. if you have several model classes for the same node type. By default Spring Data Sophora will choose the model class with the deepest level in the class hierarchy. This approach will not work when there are classes at the same level within the hierarchy. You might also want to programmatically choose the correct model class depending on some conditions.

For all these cases you can implement your custom IEntityClassResolver. A rudimentary implementation may look like this.

@Component
public class SpecialEntityClassResolver implements IEntityClassResolver {

    @Override
    public Optional<Class<? extends SophoraEntity>> resolve(INode sourceNode) {
        String primaryType = sourceNode.getPrimaryType();
        if ("sophora-example-nt:story".equals(primaryType)) {
            String externalId = sourceNode.getString("sophora:externalId");
            if ("specialSnowflake".equals(externalId)) {
                return Optional.of(SpecialStory.class);
            }
            return Optional.of(MyStory.class);
        }
        return Optional.empty();
    }

}

The above code will choose the SpecialStory class whenever a story with the external ID "specialSnowflake" shall be converted. For all other stories the MyStory class is chosen. If the document is no story, we simply return an empty Optional and let Spring Data Sophora use its default mechanic as described above.

Your entity class resolver must also be registered at your repository. This can easily be done by also inheriting from IWithEntityClassResolverRepository:

public interface MyStoryRepository extends SophoraDocumentRepository<MyStory>, IWithEntityClassResolverRepository<MyStoryRepository> {
}

and setting your SpecialEntityClassResolver like this:

@Component
public class RepositoriesProvider {
    @Getter
    private final MyStoryRepository base;
    @Getter
    private final MyStoryRepository special;

    public RepositoriesProvider(IEntityClassResolver entityClassResolver, MyStoryRepository repository) {
        this.base = repository;
        this.special = repository.withEntityClassResolver(entityClassResolver);
    }
}

Filtering content

If you need to filter the content of your repository for some reason, you have the following possibilities.

TimeFilteredRepository

The interface TimeFilteredRepository can be used to retrieve content at a specific time. This might be useful to show a preview of a document in the past or future. The time filtering will consider the state of the retrieved document as well as all its referenced documents at the given time. Example

public interface MyStoryRepository extends SophoraDocumentRepository<MyStory>, TimeFilteredRepository<MyStoryRepository> {
}
@Component
public class RepositoriesProvider {
    @Getter
    private final MyStoryRepository base;
    
    public RepositoriesProvider(MyStoryRepository repository) {
        this.base = repository;
    }

    public MyStoryRepository getBaseAtTime(Instant filterTime) {
        return base.atTime(filterTime);
    }
}

IFilteredRepository

If you want to do some additional filtering of the documents retrieved from a repository you might use the IFilteredRepository interface:

public interface MyStoryRepository extends SophoraDocumentRepository<MyStory>, IFilteredRepository<MyStoryRepository> {
}

The interface provides a method called withFilterOptions which takes a RepositoryFilterOptions object as argument. This object contains the settings that will take affect when the repository delivers the content.

@Component
public class RepositoriesProvider {
    @Getter
    private final MyStoryRepository base;
    
    public RepositoriesProvider(MyStoryRepository repository) {
        this.base = repository;
    }

    public MyStoryRepository getBaseWithFilterOptions(RepositoryFilterOptions filterOptions) {
        return documentRepository.withFilterOptions(filterOptions);
    }
}

Spring Injection (Autowiring)

Your models will not be registered as Spring beans. So if you want to inject beans into your models you have to configure your model to be "injectable". This can be done by adding the @PerformSpringAutowiring annotation to your model class. This will allow you to inject any bean that is known to the Spring context into the model:

@NodeType(value = "sophora-example-nt:story")
@PropertyNamespace("sophora-example")
@Data
@PerformSpringAutowiring
public class MyStory extends SophoraDocumentEntity {

    @Autowired
    private ISophoraClient sophoraClient;

    private String title; 
}

Searching

When you want to search for documents you usually have to perform a search query. The SophoraDocumentRepository already has some convenience methods to perform some standard queries:

Search MethodExplanation
findByExternalId(String externalId)Tries to find the document with the given external ID and returns the appropriate Java model representation.
findByUuid(UUID uuid)Tries to find the document with the given UUID and returns the appropriate Java model representation.
findBySophoraId(String sophoraId)Tries to find the document with the given Sophora ID and returns the appropriate Java model representation.
findAll()Finds all documents in the repository.
query(IQuery query, SearchParameters searchParameters)Finds all documents matching the given query and returns a list of their appropriate Java model representations.

Last modified on 8/5/21

The content of this page is licensed under the CC BY 4.0 License. Code samples are licensed under the MIT License.

Icon