인프런 커뮤니티 질문&답변

작성자 없음

작성자 정보가 삭제된 글입니다.

스프링 DB 2편 - 데이터 접근 활용 기술

외래키 중복 관련 질문

24.02.26 22:56 작성

·

190

0

import com.example.banking.domain.user.User
import com.example.banking.support.BaseEntity
import jakarta.persistence.Entity
import jakarta.persistence.FetchType
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne

@Entity
class Account(
    var balance: Double,
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    val user: User,

    id: Long = 0

) : BaseEntity(id) {
    fun addAccount(user: User) {
        user.accounts.add(this)
    }

    fun addBalance(amount: Double) {
        balance += amount
    }
    
    fun subtractBalance(amount: Double) {
        balance -= amount
    }
}
import com.example.banking.domain.account.Account
import com.example.banking.support.BaseEntity
import jakarta.persistence.*

@Entity
class Transaction(
    val amount: Double,
    @Enumerated(EnumType.STRING)
    val type: TransactionType,

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn
    val sender: Account,

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn
    val recipient: Account?,

    id: Long = 0L
) : BaseEntity(id) {
    constructor(amount: Double, type: TransactionType, sender: Account) : this(amount, type, sender, null)
}
import com.example.banking.domain.account.Account
import com.example.banking.domain.user.User
import com.example.banking.domain.user.UserInfo
import com.example.banking.repository.account.AccountRepository
import com.example.banking.repository.transaction.TransactionRepository
import com.example.banking.repository.user.UserRepository
import jakarta.persistence.EntityManager
import jakarta.transaction.Transactional
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.annotation.Rollback

@SpringBootTest
@Transactional
@Rollback(value = false)
class TransactionTest(
    @Autowired private val em: EntityManager,
    @Autowired private val transactionRepository: TransactionRepository,
    @Autowired private val userRepository: UserRepository,
    @Autowired private val accountRepository: AccountRepository

) {
    @Test
    fun testTransaction() {
        val user1 = User(UserInfo("b", "Seoul", "123", "123"))
        val user2 = User(UserInfo("b2", "Seoul", "123", "123"))

        userRepository.save(user1)
        userRepository.save(user2)

        em.flush()
        em.clear()

        val account1 = Account(100.0, user1)
        val account2 = Account(100.0, user2)


        account1.addAccount(user1)
        account2.addAccount(user2)

        accountRepository.save(account1)
        accountRepository.save(account2)

        em.flush()
        em.clear()

        val sender = accountRepository.findById(account1.id).get()
        val recipient = accountRepository.findById(account2.id).get()


        val transaction = Transaction(50.0, TransactionType.TRANSFER, sender, recipient)
        transactionRepository.save(transaction)

        em.flush()

        em.clear()


        val transaction2 = Transaction(50.0, TransactionType.DEPOSIT, sender)

        transactionRepository.save(transaction2)


//        assertThat(sender.balance).isEqualTo(50.0)
//        assertThat(recipient.balance).isEqualTo(150.0)

    }
}

 

위와같이 Transaction 엔티티와 Account 엔티티가 ManyToOne 으로 매핑되었을때, 테스트코드를 위와같이 작성시,

transactionRepository.save(transaction2)

이 라인에서 Duplicate entry '97' for key 'transaction.UK_96vb4d846be64bta5qbxiicb1' 에러가 발생합니다.
제가 알기론 외래키의 경우 중복된 값을 가지는것이 가능한것으로 알고 있는데, 같은 account id로 새로운 Transaction 을 생성할 시에 키가 중복이라는 에러가 발생하는데 왜 그런지 알고싶습니다.

 

코틀린으로 코드 작성한 점 양해부탁드립니다..

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

2024. 02. 28. 20:09

안녕하세요. co-account님

도움을 드리고 싶지만 질문 내용만으로는 답변을 드리기 어렵습니다.

자바를 기반으로 작동하는 코드를 새로 만들어주시겠어요?

그리고 전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx

 

주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요

 

추가로 다음 내용도 코멘트 부탁드립니다.

1. 문제 영역을 실행할 수 있는 방법

2. 문제가 어떻게 나타나는지에 대한 상세한 설명

 

링크: 공식 서포터즈

링크: 자주하는 질문

감사합니다.

작성자 없음

작성자 정보가 삭제된 글입니다.

질문하기