Save with H2 in Memory not working properly
See original GitHub issueI created a small project to setup the database with liquibase and save some data to a db with spring data r2dbc. I tested this with postgres and it works like a charm. With H2 i get an empty Mono back from spring data, even though the data is written to the db. Here is a minimal test-setup in Kotlin with Spring Boot 2.1.2.RELEASE, Spring data r2dbc 1.0.0.M1 and r2dbc Arabba-M7.
@RunWith(SpringRunner::class)
@SpringBootTest
@AutoConfigureWebTestClient
class IntegrationTest {
private val logger = getLogger(IntegrationTest::class.java)
@Autowired
private lateinit var testRepo: TestRepository
@Test
fun `save data in h2 memory db`() {
val testentity = Testentity(null, "Some title", "me! or I!")
val savedEntity = testRepo.save(testentity)
StepVerifier.create(savedEntity)
// .expectNext(testentity.apply {id = 1}) // FIXME: I expect an entity to be returned
.verifyComplete()
StepVerifier.create(testRepo.findAll().collectList())
.consumeNextWith { entityCount -> logger.debug("There are ${entityCount.count()} test entities saved")}
.verifyComplete()
}
}
The needed code for the application setup is as follows:
Application Context:
@SpringBootApplication
@EnableR2dbcRepositories
class DatabaseConfig: AbstractR2dbcConfiguration() {
private val logger: Logger = getLogger(javaClass)
private var DB_UUID: String = "testdb"
@Bean
override fun connectionFactory(): ConnectionFactory {
val originDataSource = dataSource().unwrap(SimpleDriverDataSource::class.java)
val config = ConnectionFactories.get(ConnectionFactoryOptions.builder()
.option(ConnectionFactoryOptions.DRIVER, "h2")
.option(ConnectionFactoryOptions.PROTOCOL, "mem")
.option(ConnectionFactoryOptions.DATABASE, DB_UUID)
.option(ConnectionFactoryOptions.USER, originDataSource.username!!)
.option(ConnectionFactoryOptions.PASSWORD, originDataSource.password!!)
.build())
val queryFormatter = QueryExecutionInfoFormatter.showAll()
return ProxyConnectionFactory.builder(config)
// Log executed query information
.onAfterQuery{queryExecInfo -> queryExecInfo
.map(queryFormatter::format)
.map(logger::trace)
.subscribe()
}.build()
}
@Bean
fun converter(mappingContext: RelationalMappingContext, r2dbcCustomConversions: R2dbcCustomConversions): MappingR2dbcConverter {
return MappingR2dbcConverter(BasicRelationalConverter(mappingContext, r2dbcCustomConversions))
}
/**
* Enable SQL Schema generation via Liquibase. A dataSource is needed for this
*/
@Bean
fun dataSource(): DataSource = EmbeddedDatabaseBuilder()
.setName(DB_UUID)
.setType(EmbeddedDatabaseType.H2)
.ignoreFailedDrops(true)
.build()
}
Entity:
@Entity
data class Testentity(
@Id
@GeneratedValue(strategy = AUTO)
var id: Long?,
@NotNull
val title: String,
@NotNull
val creator: String
)
Repository:
@Repository
interface TestRepository : ReactiveCrudRepository<Testentity, Long>
Liquibase create table file:
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet id="1" author="numbernick">
<createTable tableName="testentity">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="title" type="varchar(500)"/>
<column name="creator" type="varchar(500)">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
</databaseChangeLog>
The output of the test shows that the save-methods works (it persists data), but does not return the saved data:
20-03-2019 13:06:39.346 [main] TRACE d.n.t.r.DatabaseConfig$$EnhancerBySpringCGLIB$$8f98f76c.invoke - Thread:main(1) Connection:1 Transaction:{Create:0 Rollback:0 Commit:0} Success:True Time:11 Type:Statement BatchSize:0 BindingsSize:1 Query:["INSERT INTO testentity (title, creator) VALUES($1, $2)"] Bindings:[(Some title,me! or I!)]
20-03-2019 13:06:39.366 [main] DEBUG d.n.test.reactiveh2.IntegrationTest.accept - There are 1 test entities saved
20-03-2019 13:06:39.366 [main] TRACE d.n.t.r.DatabaseConfig$$EnhancerBySpringCGLIB$$8f98f76c.invoke - Thread:main(1) Connection:2 Transaction:{Create:0 Rollback:0 Commit:0} Success:True Time:10 Type:Statement BatchSize:0 BindingsSize:0 Query:["SELECT id, title, creator FROM testentity"] Bindings:[]
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (2 by maintainers)
Top Results From Across the Web
Repository doesn't save data to H2 in-memory db
I'm going to change my db later on, just using H2 to check if my controllers work fine but it shouldn't matter here....
Read more >H2 Database Spring Boot - How to connect and configure an ...
In this tutorial, you will learn everything you need to know to connect and configure an in- memory H2 database in Spring Boot....
Read more >Spring Boot and H2 in memory database - in28minutes
An in memory database is created when an application starts up and destroyed when the application is stopped. Advantages. Zero project setup or ......
Read more >Tutorial - H2 Database Engine
Open a file browser, navigate to h2/bin , and double click on h2.bat . A console window appears. If there is a problem,...
Read more >Spring Boot With H2 Database - Baeldung
By design, the in-memory database is volatile, and results in data loss after application restart. We can change that behavior by using file- ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Looks like this is a driver-level issue. I need to inspect the flag options that can be supplied to H2, signaling to return the new key instead of row count. Given we are inside the internals of H2 (no external/internal boundary outside of JDBC APIs), this can get tricky.
For the record: This issue seems to be solved in Arabba-M8 reactiveh2-M8.zip