// C++ includes used for precompiling -*- C++ -*-
// Copyright (C) 2003-2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file stdc++.h
* This is an implementation file for a precompiled header.
*/
// 17.4.1.2 Headers
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif
// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
MariaDB [bim_library]> delete from library_info where library_no between 1 and 50;
ERROR 1451 (23000): Cannot delete or update a parent row:
a foreign key constraint fails
(`bim_library`.`tag`, CONSTRAINT `FK2tk1sqt8jfmgqn7st8l73214`
FOREIGN KEY (`library_no`) REFERENCES `library_info` (`library_no`))
준영속 상태로 만든 다음 데이터를 세팅하고, 다시 엔티티 매니저의 관리대상이 되도록 persist() 하라는 답변이었다.
Member엔티티의 PK를 FK로 사용하는 엔티티의 정보까지 바뀌도록 신경써야 해서 삽질이 길었다.
Member엔티티를 persist() 하기 전에, FK로 연관된 엔티티들을 일일이 set해줬다.
Member 엔티티와 연관관계에 있는 엔티티들은 전부 Cascade.Type All로 설계했기 때문에 다 연결되어 있었기 때문이다.
수정한 예시 코드다.
아래와 같은 흐름으로 수정하여 해결할 수 있었다.
Long targetId = 1L;
Member oldMember = em.find(Member.class, targetId);
Hobby oldHobby = oldMember.getHobby();
em.detach(oldMember); // 준영속 상태로 만든다. (JPA가 관리하지 않는 객체가 된다)
oldMember.setName("minzy");
oldMember.setId(targetId + 1L); // PK를 1증가시킨다
oldMember.setHobby(oldHobby); // 연관관계에 있는 엔티티 정보도 set해야 한다.
em.persist(oldMember); // 영속성 컨텍스트의 1차 캐시에 올라가도록, 영속 상태로 만든다.