spring-fu icon indicating copy to clipboard operation
spring-fu copied to clipboard

Name R2dbcEntityTemplate explicitly

Open peterfigure opened this issue 3 years ago • 6 comments

I believe this isn't fully supported yet but attempting to use r2dbc DSL with repositories, pretty close but I believe it wants the R2dbcEntityTemplate bean named "r2dbcEntityTemplate" explicitly:

https://github.com/spring-projects/spring-data-r2dbc/blob/1.2.x/src/main/java/org/springframework/data/r2dbc/repository/config/EnableR2dbcRepositories.java#L139

19:31:29.421 [restartedMain] WARN  o.s.b.w.r.c.AnnotationConfigReactiveWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contractLifecycleRepository' defined in com.xxx.ContractLifecycleRepository defined in @EnableR2dbcRepositories declared on R2dbcRepositoriesAutoConfigureRegistrar.EnableR2dbcRepositoriesConfiguration: Cannot resolve reference to bean 'r2dbcEntityTemplate' while setting bean property 'entityOperations'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'r2dbcEntityTemplate' available

When creating the beans manually in lieu of using r2dbc DSL I run into the same problem and it's resolved by naming it explicitly:

        bean<R2dbcEntityTemplate>("r2dbcEntityTemplate") {
            ref<R2dbcDataAutoConfiguration>().r2dbcEntityTemplate(ref())
        }

peterfigure avatar Dec 11 '20 21:12 peterfigure

Hi @peterfigure R2dbcEntityTemplate are actually supported using the dataR2dbc dsl. We splitted r2dbc and dataR2dbc to allow users that want to use only low-level r2dbc without spring-data-r2dbc could do it (see #314 for details).

You can find a sample here and specifically for the configuration :

configuration {
    dataR2dbc {
        r2dbc {
            url = "r2dbc:h2:mem:///testdb;DB_CLOSE_DELAY=-1"
        }
    }
}

The R2dbcEntityTemplate is registered using this DSL but I'm not sure about the name. Could you check with this configuration if the error is still happening ?

fteychene avatar Dec 14 '20 14:12 fteychene

hi @fteychene - tried to extract a minimal project illustrating some of my challenges:

https://github.com/peterfigure/minimal-kofu

please start postgres with the included docker-compose.yaml and then run com.peterfigure.Application.main(), it should show you the missing reference to entity template.

In com.peterfigure.config.ApplicationConfigurationDSL please uncomment bean<R2dbcCustomConversions>() to see the issue I've encountered and mentioned in my other ticket.

peterfigure avatar Dec 14 '20 17:12 peterfigure

when I use my forked spring-fu:

~/develop/spring-fu-fork  ‹peterfigure/add_buildinfo_dsl*› $ git diff
diff --git a/autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataInitializer.java b/autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataInitializer.java
index 650a05ea..6e310069 100644
--- a/autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataInitializer.java
+++ b/autoconfigure-adapter/src/main/java/org/springframework/boot/autoconfigure/data/r2dbc/R2dbcDataInitializer.java
@@ -47,7 +47,7 @@ public class R2dbcDataInitializer implements ApplicationContextInitializer<Gener
             }
         };
 
-        context.registerBean(R2dbcEntityTemplate.class, () -> r2dbcDataConfiguration.get().r2dbcEntityTemplate(context.getBean(R2dbcConverter.class)));
+        context.registerBean("r2dbcEntityTemplate", R2dbcEntityTemplate.class, () -> r2dbcDataConfiguration.get().r2dbcEntityTemplate(context.getBean(R2dbcConverter.class)));
         context.registerBean(R2dbcCustomConversions.class, () -> r2dbcDataConfiguration.get().r2dbcCustomConversions());
         context.registerBean(R2dbcMappingContext.class, () -> r2dbcDataConfiguration.get().r2dbcMappingContext(context.getBeanProvider(NamingStrategy.class), context.getBean(R2dbcCustomConversions.class)));
         context.registerBean(MappingR2dbcConverter.class, () -> r2dbcDataConfiguration.get().r2dbcConverter(context.getBean(R2dbcMappingContext.class), context.getBean(R2dbcCustomConversions.class)));

it works.

peterfigure avatar Dec 14 '20 17:12 peterfigure

After testing the naming is required indeed.

@sdeleuze What do you think about naming the R2dbcEntityTemplate created by dataR2dbc since it seems that other parts depends on it by bean naming convention ?

In the mean time this configuration seems to be working With this configuration the application boot :

fun databaseConfiguration(databaseConfig: DatabaseConfig): ConfigurationDsl {
        return configuration {
            r2dbc {
                url = databaseConfig.url
                transactional = true // creates transactional operator
                optionsCustomizers = connectionFactoryOptionsCustomizers(databaseConfig)
                username = databaseConfig.username
                password = databaseConfig.password
            }
            beans {
                bean("r2dbcEntityTemplate") { R2dbcEntityTemplate(ref<ConnectionFactory>()) }
            }
        }
    }

fteychene avatar Dec 14 '20 20:12 fteychene

Thanks @fteychene - ~~were you able to replicate the other issue with R2dbcCustomConversions?~~ actually i'll update the other issue to be a bit more coherent (not very familiar with spring or kofu in general)

peterfigure avatar Dec 14 '20 20:12 peterfigure

@fteychene Yeah we need to set this name, I had to do the same for other part of this infra that rely on name as well like on web.

sdeleuze avatar Jan 08 '21 10:01 sdeleuze