When running my application (Spring Boot 2.5.7) - after updating to spring-data-r2dbc 1.3.7, I get the NoSuchMethodError RowMetadata.getColumnMetadatas()
.
(I have also tried this with 1.4.0 - 1.3.7 is where the problem first surfaces.)
In this spring-data-r2dbc release, a change has been made to move off of getColumnNames
(See https://github.com/spring-projects/spring-data-r2dbc/issues/683) to getColumnMetaDatas()
.
What is odd is that I also have the dependencies
- r2dbc-spi - 0.9.0.RELEASE
- org.postgresql:r2dbc-postgresql - 0.9.0.RC1
The 0.9.0 RC1 of r2dbc-postgresql fulfills the spi contract. So, it seems that everything should be in place -
The correct version of spring-data-r2dbc (1.3.7) invokes getColumnMetaDatas()
:
public static boolean containsColumn(RowMetadata metadata, String name) {
for (ColumnMetadata columnMetadata : metadata.getColumnMetadatas()) {
if (name.equalsIgnoreCase(columnMetadata.getName())) {
return true;
}
}
return false;
}
which is a method of the 0.0.9.RELEASE r2dbc-spi interface RowMetaData
, which is fulfilled by the 0.9.0.RC1 version of r2dbc-postgresql PostgresqlRowMetadata
.
I have looked at my maven dependency tree and see no competing versions of any of these.
I could assume that the binding of the implementation to the spi is bad, but I got far enough to make the call to the database and then try to extract the data, so that doesn't seem right. So, it appears that something else is off.
I added the command line option -verbose:class
to see what classes/jars are being loaded and things look correct from there as well:
[30.756s][info][class,load] io.r2dbc.postgresql.message.frontend.CompositeFrontendMessage$$Lambda$2382/0x0000000800ee3840 source: io.r2dbc.postgresql.message.frontend.CompositeFrontendMessage
[30.756s][info][class,load] io.r2dbc.postgresql.message.frontend.Bind$$Lambda$2383/0x0000000800ee3c40 source: io.r2dbc.postgresql.message.frontend.Bind
[30.757s][info][class,load] io.r2dbc.postgresql.message.frontend.Bind$$Lambda$2384/0x0000000800ee4040 source: io.r2dbc.postgresql.message.frontend.Bind
[30.757s][info][class,load] io.r2dbc.postgresql.message.frontend.Bind$$Lambda$2385/0x0000000800ee4440 source: io.r2dbc.postgresql.message.frontend.Bind
[30.761s][info][class,load] io.r2dbc.postgresql.message.backend.ParseComplete source: file:/<removed>/.m2/repository/org/postgresql/r2dbc-postgresql/0.9.0.RC1/r2dbc-postgresql-0.9.0.RC1.jar
[30.762s][info][class,load] org.springframework.data.r2dbc.convert.RowMetadataUtils source: file:/<removed>/.m2/repository/org/springframework/data/spring-data-r2dbc/1.3.7/spring-data-r2dbc-1.3.7.jar
Stack Trace:
java.lang.NoSuchMethodError:
io.r2dbc.spi.RowMetadata.getColumnMetadatas()Ljava/lang/Iterable;
at org.springframework.data.r2dbc.convert.RowMetadataUtils.containsColumn(RowMetadataUtils.java:38)
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.extractGeneratedIdentifier(MappingR2dbcConverter.java:646)
... 2 frames excluded
at io.r2dbc.postgresql.PostgresqlResult.lambda$map$2(PostgresqlResult.java:123)
at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(...
I've also
- Updated my JDK to the latest version of Corretto 1.8
- Compiled spring-data-r2dbc 1.4.0 with that version and used it
- Inserted code in RowMetaDataUtils to reflect and log the methods found in the
metadata
parameter ofcontainsColumn(...)
. The results includepublic java.util.List<io.r2dbc.postgresql.PostgresqlColumnMetadata> io.r2dbc.postgresql.PostgresqlRowMetadata.getColumnMetadatas()
, which makes this even more perplexing.
I'll try and get a test that duplicates this - but hope that somebody has an idea for me to try to fix or debug with.