spring-projects / spring-data-relational

Spring Data Relational. Home of Spring Data JDBC and Spring Data R2DBC.

Home Page:https://spring.io/projects/spring-data-jdbc

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add Entity Inheritance Support

hantsy opened this issue · comments

I have a table bank_accounts support business accounts and personal accounts. The following example codes is added into https://github.com/hantsy/spring-r2dbc-sample/tree/master/jooq-kotlin-co-gradle

Db schema:

CREATE TABLE IF NOT EXISTS bank_accounts (
     id UUID  NOT NULL /* [jooq ignore start] */DEFAULT uuid_generate_v4()/* [jooq ignore stop] */,
     business_name VARCHAR(255),
     account_number VARCHAR(50) NOT NULL,
     routing_number VARCHAR(50) NOT NULL,
     first_name VARCHAR(255),
     last_name VARCHAR(255)
);

ALTER TABLE bank_accounts ADD CONSTRAINT bank_accounts_pk PRIMARY KEY (id);

Entity classes:

@Table("bank_accounts")
sealed class BankAccount(
    @Id
    open val id: UUID? = null,

    @Column(value = "account_number")
    open  var accountNumber: String? = null,

    @Column(value = "routing_number")
    open var routingNumber: String? = null
)

data class BusinessBankAccount(
    override val id: UUID? = null,
    override var accountNumber: String? = null,
    override var routingNumber: String? = null,
    @Column(value = "business_name")
    var businessName: String? = null

) : BankAccount()

data class IndividualBankAccount(
    override val id: UUID? = null,
    override var accountNumber: String? = null,
    override var routingNumber: String? = null,
    @Column(value = "first_name")
    var firstName: String? = null,

    @Column(value = "last_name")
    var lastName: String? = null
) : BankAccount()

Repository class:

interface BankAccountRepository : CoroutineSortingRepository<BankAccount, UUID>,
    CoroutineCrudRepository<BankAccount, UUID> {
}

But when I have a try with the following codes.

val companyBankAccount = BusinessBankAccount(
    accountNumber = "test",
    routingNumber = "routetest",
    businessName = "business name"
)
bankAccountRepository.save(companyBankAccount)

val personalBankAccount = IndividualBankAccount(
    accountNumber = "test",
    routingNumber = "routetest",
    firstName = "first name",
    lastName = "last name"
)

bankAccountRepository.save(personalBankAccount)

bankAccountRepository.findAll().toList().forEach {
    log.debug("saved bank accounts: $it")
}

And got the exception like this.

2024-03-01T13:15:17.570+08:00 DEBUG 6816 --- [s.test runner#4] o.s.r2dbc.core.DefaultDatabaseClient     : Executing SQL statement [INSERT INTO bank_accounts (business_name) VALUES ($1)]

org.springframework.dao.DataIntegrityViolationException: executeMany; SQL [INSERT INTO bank_accounts (business_name) VALUES ($1)]; null value in column "account_number" violates not-null constraint
	at _COROUTINE._BOUNDARY._(CoroutineDebugging.kt:46)
	at com.example.demo.BankAccountPostRepositoryTest$query sample data$1.invokeSuspend(BankAccountPostRepositoryTest.kt:77)
	at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTest$2$1$1.invokeSuspend(TestBuilders.kt:314)

Duplicate of #627