Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nft와 wallet 중복 키 발생이슈 #11

Merged
merged 1 commit into from
Mar 31, 2024
Merged

Conversation

min-96
Copy link
Contributor

@min-96 min-96 commented Mar 31, 2024

관련 이슈 #10

#2 해당이슈 참고
테이블 설계당시 간과하던 사실이 있었음, 지갑 주소를 키로 뒀을시 해당 지갑에 network가 추가되면서 wallet테이블에 network만 다르게 추가되어야 되는데 지갑주소를 PK로 두기때문에 에러가 발생함

또한 nft를 식별하는건 nft의 token 주소가 아닌 token주소와 token_Id임

그래서 내가 해결방법은 wallet(address,networkType) / nft(address,tokenId)를 복합키로 두자라고 생각함

하지만 안타깝게도 r2dbc는 복합키를 지원하지 않는다는거였음
spring-projects/spring-data-relational#574
5년이 지난 아직도 지원을 안한다니 R2DBC를 사용하면서 JPA 찬양만 더 하게됨

댓글에서 dto클래스를 만들어 복합키로 설정해보라는 설명이 나와있어서 복합키를 사용해보려고함

못먹어도 GO 삽질 시작

@Table("wallet")
data class Wallet(
    @Id val id: WalletId,
    val userId: Long,
    var balance: BigDecimal,
    val createdAt: Long? = System.currentTimeMillis(),
    var updatedAt: Long? = System.currentTimeMillis()
)

data class WalletId(
    val address: String,
    val networkType: String,
)

CREATE TABLE IF NOT EXISTS wallet (
    address VARCHAR(255) NOT NULL,
    balance DECIMAL(19, 4) NOT NULL,
    created_At BIGINT,
    updated_At BIGINT,
    user_id BIGINT NOT NULL,
    network_type VARCHAR(100) NOT NULL,
        CONSTRAINT fk_users
             FOREIGN KEY (user_id)
             REFERENCES users(id),
        CONSTRAINT fk_network
            FOREIGN KEY (network_type)
            REFERENCES network(type),
        PRIMARY KEY (address, network_type)
);

"SELECT * FROM wallet WHERE address = $1 AND network_type = $2" 실행 후 wallet을 잘 가져오길 기대했지만
객체에 데이터바인딩 안되는 문제가 발생함 ..."not supported xxxxxx"

 override fun findById(address: String, networkType: String): Mono<Wallet> {
       val query =
          "SELECT * FROM wallet WHERE address = $1 AND network_type = $2"

      return r2dbcEntityTemplate.databaseClient.sql(query)
          .bind(0, address)
          .bind(1, networkType)
          .map { row, metadata ->
              Wallet(
                  id = WalletId(address = row.get("address", String::class.java)!!,
                      networkType = row.get("network_type", String::class.java)!!),
                  userId = (row.get("user_id") as Number).toLong(),
                  balance = row.get("balance", BigDecimal::class.java)!!,
                  createdAt = (row.get("created_at") as Number).toLong(),
                  updatedAt = (row.get("updated_at") as Number).toLong(),
              )
          }.first()
  }

이렇게 직접 객체매핑을 해줘야된다는 단점이있음
마찬가지로 inser문 ,update문에서도 파라미터를 바인딩해줘서 insert쿼리와 Update쿼리를 작성해줘야된다는 단점이 있었음
복합키 관리에 대한 어려움을느낌..
wallet과 nft는 연관관계 테이블이 많기때문에, 연관관계인 테이블을 insert하려고 할때에도 직접 query를 작성해야됨

4시간동안 삽질 후

결론 : 그냥 PK를 따로두고 필드로 두기로 함

태초의 JDBC로 돌아간 느낌이라 NFT서버에서는 JPA를 사용할까 심히 고민중임

@min-96 min-96 merged commit dc813b6 into develop Mar 31, 2024
@min-96 min-96 self-assigned this Mar 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant