OpenNTF / org.openntf.xsp.jakartaee

XPages Jakarta EE support libraries
Apache License 2.0
21 stars 7 forks source link

Custom Repository methods #460

Open monstermichl opened 1 year ago

monstermichl commented 1 year ago

Hello, is it possible to add custom DominoRepository methods apart from the syntax specified by Jakarta EE NoSql? I would like to do some specific querying on the documents without the need to define a view. Thanks.

jesse-gallagher commented 1 year ago

There are a few ways to go about it:

You should be able to use the @Query annotation with a repository method (that's jakarta.nosql.mapping.Query) to use NoSQL's SQL-like syntax, which is carried over to Jakarta Data in versions later than what I have here currently: http://www.jnosql.org/spec/#_using_the_query_annotation . The idea should be the same, though - it can be a bit more flexible than just the implicit generation based on method name.

You can also use the DominoTemplate interface to query using the Java-based syntax. To do that, you can inject the template in a CDI bean:

@Inject @Database(value=DatabaseType.DOCUMENT, provider="optionalRepoName")
private DominoTemplate template

Then, you can perform a query like:

DocumentQuery query = DocumentQuery.builder().from("Project").where(DocumentCondition.eq("Owner", userInfo.getName())).build();
Stream<Project> projects = template.select(query);
monstermichl commented 1 year ago

Thanks for the answer, Jesse. Basically, this is a good idea but I would like to have these functions in a generic base interface/class which doesn't know anything about which tables to use.

import java.util.stream.Stream;
import org.openntf.xsp.nosql.mapping.extension.DominoRepository;

public interface CommonDominoDocumentRepository<T> extends DominoRepository<T, String> {
    public Stream<T> findAll();
}
public interface ArtistRepository extends CommonDominoDocumentRepository<Artist> {
}

If I would use the approach with the Database injection, I would need to provide the correct Repository-name as well, right? Because how does the Database else know which Repository derivation to use? Additionally, I would have to provide the Database name (e.g. "Project") in the query itself, which would not be that big of a deal but I would like to keep this information in the Entity.

jesse-gallagher commented 10 months ago

I've been pondering the best way to handle looser mixes of DBs and entities, and have an old issue to deal with it some day: https://github.com/OpenNTF/org.openntf.xsp.jakartaee/issues/251 . It can be a bit odd that entities themselves don't have a binding to a DB, but it at least pays off when it comes to generic document types that may be in multiple DBs.

Right now, there's the @RepositoryProvider annotation you can put on repositories that lets you point to a bean to provide the DB: https://github.com/OpenNTF/org.openntf.xsp.jakartaee#document-sources . Unfortunately, there's no sense of dynamic context there, like seeing what repository was asking for it or any other conditionals, meaning it doesn't really solve the problem of wanting to use the same repository definition with different DBs.

I'll likely investigate options for this when I move to Jakarta Data in the 3.x range of the project, since that will reshuffle some of the assumptions anyway.