마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

일대다 관계에서 자식 Entitiy 아이디

0 추천

현재 추가버튼을 누르면 WorkoutSetInfo라는 아이템이 리스트에 추가되고 (DB에 Insert 하지않음)

다 추가되면 저장버튼을 눌러 Workout과 함께 WorkoutSetInfo리스트가 함께 DB에 Insert 시키는 것을 만들고 있습니다.

어느정도 되긴했는데.. 위에서도 언급했다시피 Workout과 WorkoutSetInfo 리스트 정보가 최종적으로 마지막에 저장버튼을 눌렀을때 한번에 넣는 식이다 보니 

자식 Entity(WorkoutSetInfo)에서 부모 Entity(Workout)을 참조하기위핸 ForeignKey의 세팅을 어떻게 설정(가져와야)할지 모르겠습니다..

현재는 test한다고 고정값 1로 설정해놓았는데

Workout이 추가될때마다 Workout의 값은 달라지는데 이게 고정 1이 될순 없잖아요?

그래서 workoutId를 가져와서 WorkoutSetInfo를 생성할때 파라미터로 줘봤는데 에러가나더군요..

FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY[787])

에러요.. 검색해보니 부모테이블에 존재하지않은 외래키를 추가해서 이런 에러가 발생하는것같다는데..

어떻게 해결해야좋을까요

Workout

@Entity
data class Workout(
    @PrimaryKey(autoGenerate = true)
    val workoutId: Long = 0,
    val title: String = "",
    var unit: String = "kg",
    val memo: String = "",
)

 

WorkoutSetInfo

@Entity(
    foreignKeys = [
        ForeignKey(
            entity = Workout::class,
            parentColumns = arrayOf("workoutId"),
            childColumns = arrayOf("parentWorkoutId"),
            onDelete = ForeignKey.CASCADE // 부모가 삭제될때 자식도 전부삭제 옵션
        )
    ]
)
data class WorkoutSetInfo(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0, // UUID 비교를 위한 ID
    val set: Int,
    var weight: String = "",
    var reps: String = "",
    val parentWorkoutId: Long
)

 

WorkoutWithSets

data class WorkoutWithSets(
    @Embedded val workout: Workout,
    @Relation (
        parentColumn = "workoutId" ,
        entityColumn = "parentWorkoutId"
    )
    val sets: List<WorkoutSetInfo>
)

 

Repository

class WorkoutRepository(private val workoutDao : WorkoutDao, title: String) {
    val workout = Workout(title = title)
    private val setInfoList = ArrayList<WorkoutSetInfo>()

    fun add() {
        val item = WorkoutSetInfo(set = setInfoList.size + 1, parentWorkoutId = workout.workoutId)
        setInfoList.add(item)
    }

    fun save() {
        workoutDao.insertWorkout(workout)
        workoutDao.insertSetInfoList(setInfoList)
    }

    // toList를 하는 이유는 새로운 리스트를 반환하기때문에 postValue 가능하게끔 하기 위함
    fun getList() : List<WorkoutSetInfo> = setInfoList.toList()
}

 

 

 

 

 

codeslave (3,940 포인트) 님이 2022년 5월 10일 질문

1개의 답변

0 추천
 
채택된 답변

Workout에 사용하는 키를 autogenate가 아니라 수동으로 생성하시거나,

DAO의 @Insert 함수의 리턴타입을 long이나 long[](여러 레코드의 경우)로 하시면 마지막에 저장했던 데이터의   id필드값을 리턴해 줍니다. 이걸 받아서 WorkoutSetInfo의 parentWorkoutId칼럼에 사용하시면 됩니다.

long workoutId = workoutDao.insert(workoutEntity);
val workoutSetInfos: List<WorkoutSetInfo> = userWorkoutSets.map { userWorkoutSet ->
   userWorkoutSet.copy(parentWorkoutId = workoutId)
}
workoutSetDao.insert(workoutSetInfos);

 

spark (227,470 포인트) 님이 2022년 5월 10일 답변
codeslave님이 2022년 5월 11일 채택됨
감사합니다 대강 해결하였습니다!
...