Open rbleuse opened 2 years ago
Looks like as() is being passed a null.
133 public <R> FindByQueryWithConsistency<R> as(Class<R> returnType) {
134 Assert.notNull(returnType, "returnType must not be null!");
It would be helpful to see
com.rbleuse.spring.reactive.couchbase.service.PersonService.getProjectionByName(PersonService.kt:13)
Also :
If the domain class is annotated with the module-specific type annotation, it is a valid candidate for the particular Spring Data module. Spring Data modules accept either third-party annotations (such as JPA’s @Entity) or provide their own annotations
I'm not sure about OnetoOne.
It would be helpful to see com.rbleuse.spring.reactive.couchbase.service.PersonService.getProjectionByName(PersonService.kt:13)
Just a simple service :
@Service
class PersonService(
private val repository: PersonRepository
) {
fun createPerson(person: Person) = repository.save(person)
fun getProjectionByName(name: String) = repository.findByName(name)
}
I updated my dummy repository on https://github.com/rbleuse/spring-reactive-couchbase/tree/projection (branch projection
) if you would like to investigate on it
edit: getTypeToRead() is returning null even though it has enough information to determine the return type. I'm still investigating.
124: private Object execute(ParametersParameterAccessor parameterAccessor) {
Class<?> typeToRead = processor.getReturnedType().getTypeToRead();
As a work-around when only one simple property is being returned (in your case Name contains only a String), the method can be defined to return that simple time and it will work
fun findByName(name: String): Flux<String>
Name needs to be a class. This will suffice:
class Name(var name: String) {
}
It seems that some better diagnostics would help.
Thanks, indeed with a class it's working.
However I tried to proceed to the same with a custom n1ql instead of using the method name, but I faced this exception :
interface PersonRepository : ReactiveCouchbaseRepository<Person, String> {
@Query("select p.firstName, p.lastName from #{#n1ql.bucket} p WHERE p.firstName = '#{[0]}' AND p.#{#n1ql.filter}")
fun findByFirstName(firstName: String): Flux<PersonName>
}
@Document
@Scope("dev")
@Collection("person")
data class Person(
@field:Id
val id: String,
@field:Field
val firstName: String,
@field:Field
val lastName: String
)
data class PersonName(val firstName: String, val lastName: String)
So it seems with a custom query we have to query the document id as well ? I have a concrete use case which is not that one, but this is a minimal repro of the issue I'm facing with my use case
Yes. An id is(was) always expected for an entity. Also cas. It doesn't matter what it is though. You can have "" as id, 0 as cas.
There is a change to only require id and cas if they are needed : https://github.com/spring-projects/spring-data-couchbase/issues/1402
That shows commits in main (May 3), 4.4.x (May 9) and 4.3.x (May 11). So it will be in the releases of those which occurred after (June 20 and July 15) https://calendar.spring.io/. July 15 shows 2021.1.6 -> 4.3.6, 2021.2.2 -> 4.4.2 and 2022.0.0 -> 5.0.0-M5.
Oh understood, so under the hood fun findByName(name: String): Flux<Name>
will fetch the id even though it's not mapped in my projection dto
And for a manual custom query projection, I also need to add an __id
to my query even if I don't need it.
Indeed it's working as expected if I don't declare it in my projection dto as long as I add the id in my query. Thank you !
I also need to add an __id to my query even if I don't need it.
Or you could just use the newer version that doesn't require it.
Which newer version are you referring to ?
I'm using 4.4.2 and it's still required with latest 4.4.3-SNAPSHOT
select p.firstName, p.lastName from #{#n1ql.bucket} p WHERE p.firstName = $1 AND p.#{#n1ql.filter}
com.couchbase.client.core.error.CouchbaseException: __id was null. Either use #{#n1ql.selectEntity} or project __id
at org.springframework.data.couchbase.core.ReactiveCouchbaseTemplateSupport.lambda$decodeEntity$5(ReactiveCouchbaseTemplateSupport.java:117) ~[spring-data-couchbase-4.4.3-SNAPSHOT.jar:4.4.3-SNAPSHOT]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
*__checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
*__checkpoint ⇢ HTTP POST "/person" [ExceptionHandlingWebHandler]
My mistake - the id is always required when anything other than one simple field is projected. So just project "" as __id.
Hello,
I was following the [DTO Projection](https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/#couchbase.ansijoins:~:text=Iterable%3CAirport%3E%20findAll()%3B%0A%0A%7D-,5.3.4.%20DTO%20Projections,-Spring%20Data%20Repositories) documentation but can't make it work.
My set up : spring-boot 2.7.3 (data couchbase 4.4.2)
First, this documentation has example using spring data JPA (
@Entity
and@OneToOne
annotations). Is it normal ?Second, here is my simple test and the exception I get :
Person document :
Projection interface :
Person repository :
Exception :
Is the documentation is up to date, and can we use projection with spring data couchbase ?