-
Notifications
You must be signed in to change notification settings - Fork 364
Closed
Description
In the readme of https://github.com/pgjdbc/r2dbc-postgresql, a Postgres bytea
can be mapped to byte[]
, ByteBuffer
and R2dbc Blob
.
But I tried to create a simple Spring Boot 3.x to experience it, only the byte[]
works.
@Data
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(value = "posts")
class Post {
@Id
@Column("id")
private UUID id;
@Column("title")
private String title;
@Column("content")
private String content;
@Column("attachment")
private ByteBuffer attachment;
@Column("cover_image")
private byte[] coverImage;
@Column("cover_image_thumbnail")
private Blob coverImageThumbnail;
}
And schema sql script is:
CREATE TABLE IF NOT EXISTS posts (
id UUID DEFAULT uuid_generate_v4(),
title VARCHAR(255),
content VARCHAR(255),
attachment bytea,
cover_image bytea,
cover_image_thumbnail bytea,
PRIMARY KEY (id)
);
In my tests I tried to use these types to read and write a bytea
.
@DataR2dbcTest()
@Testcontainers
@Slf4j
public class PostRepositoryTest {
@Container
static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer<>("postgres:12")
.withCopyFileToContainer(MountableFile.forClasspathResource("init.sql"), "/docker-entrypoint-initdb.d/init.sql");
@DynamicPropertySource
static void registerDynamicProperties(DynamicPropertyRegistry registry) {
registry.add("spring.r2dbc.url", () -> "r2dbc:postgresql://"
+ postgreSQLContainer.getHost() + ":" + postgreSQLContainer.getFirstMappedPort()
+ "/" + postgreSQLContainer.getDatabaseName());
registry.add("spring.r2dbc.username", () -> postgreSQLContainer.getUsername());
registry.add("spring.r2dbc.password", () -> postgreSQLContainer.getPassword());
}
@Autowired
R2dbcEntityTemplate template;
@Autowired
PostRepository posts;
@BeforeEach
public void setup() {
}
@Test
public void testDatabaseClientExisted() {
assertNotNull(template);
}
@Test
public void testPostRepositoryExisted() {
assertNotNull(posts);
}
@Test
public void testByteBuffer() {
String s = "testByteBuffer";
var post = Post.builder().title("r2dbc").attachment(ByteBuffer.wrap(s.getBytes())).build();
posts.save(post)
.as(StepVerifier::create)
.consumeNextWith(saved -> {
assertThat(saved.getTitle()).isEqualTo("r2dbc");
var attachment = new String(saved.getAttachment().array());
assertThat(attachment).isEqualTo(s);
}
)
.verifyComplete();
}
@Test
public void testByteArray() {
String s = "testByteArray";
var post = Post.builder().title("r2dbc").coverImage(s.getBytes()).build();
posts.save(post)
.as(StepVerifier::create)
.consumeNextWith(saved -> {
assertThat(saved.getTitle()).isEqualTo("r2dbc");
var attachment = new String(saved.getCoverImage());
assertThat(attachment).isEqualTo(s);
}
)
.verifyComplete();
}
@Test
public void testBlob() {
String s = "testBlob";
var post = Post.builder().title("r2dbc").coverImageThumbnail(Blob.from(Mono.just(ByteBuffer.wrap(s.getBytes())))).build();
posts.save(post)
.as(StepVerifier::create)
.consumeNextWith(saved -> {
assertThat(saved.getTitle()).isEqualTo("r2dbc");
var latch = new CountDownLatch(1);
Mono.from(saved.getCoverImageThumbnail().stream())
.map(it -> new String(it.array()))
.subscribe(it -> {
assertThat(it).isEqualTo(s);
latch.countDown();
});
try {
latch.await(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
)
.verifyComplete();
}
}
Only the byte[]
case works, other two cases(ByteBuffer
and Blob
) throw exception like this.
java.lang.AssertionError: expectation "consumeNextWith" failed (expected: onNext(); actual: onError(org.springframework.dao.InvalidDataAccessApiUsageException: Nested entities are not supported))
...
Suppressed: org.springframework.dao.InvalidDataAccessApiUsageException: Nested entities are not supported
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.writePropertyInternal(MappingR2dbcConverter.java:409)
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.writeProperties(MappingR2dbcConverter.java:376)
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.writeInternal(MappingR2dbcConverter.java:347)
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.write(MappingR2dbcConverter.java:339)
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.write(MappingR2dbcConverter.java:66)
at org.springframework.data.r2dbc.core.DefaultReactiveDataAccessStrategy.getOutboundRow(DefaultReactiveDataAccessStrategy.java:174)
at org.springframework.data.r2dbc.core.R2dbcEntityTemplate.lambda$doInsert$7(R2dbcEntityTemplate.java:479)
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:152)
... 79 more
The Sample project is here, https://github.com/hantsy/spring-r2dbc-sample/tree/master/boot-filepart
RobertHeim
Metadata
Metadata
Assignees
Labels
type: bugA general bugA general bug