LoginSignup
1
2

More than 5 years have passed since last update.

Spring Data JPA において、 外部制約違反でエンティティをパーシストできない現象について

Last updated at Posted at 2018-02-23

概要

Spring Data JPA において、Cascase.ALL のリレーションがあるエンティティのインサート時に、Many 側からの INSERT が発生したため、外部制約違反が発生してしまう現象が発生しました。
下記の例ですと、order から insert が実行されるので、親である user に insert される order の userNo が存在していません。
そのため、外部キー制約にて例外が発生しました。

User.java
@Entity
@Getter
@NoArgsConstructor
public class User {

    @Id
    private String userNo;

    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Order> orders;
}
Order.java
@Entity
@NoArgsConstructor
public class Order {

    @Getter
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Getter
    private String userNo;

    @ManyToOne
    @JoinColumn(name = "user_no", updatable = false, insertable = false)
    private User user;
}

例外が発生する SQL

insert into order (id, user_no ...) values (1, '001' ...);

原因

JpaRepository にて該当の User オブジェクトを取得しているため、EntityManager の管理下にあるためでした。
EntityManager#detach を実行することで、user から insert が実行され、正常に order を登録できました。

UserRepository.java


@Repository
public interface UserRepository extends JpaRepository<User, Integer> {

    @EntityGraph(value = "user", attributePaths = "orders", type = EntityGraph.EntityGraphType.LOAD)
    Optional<User> findOne(String userNo);
}
UserService.java
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final EntityManager em;

    @Override
    public User getUser(String userNo) {
        Optional<User> optional = userRepository.findOne(userNo);
        User result = optional.get();
        em.detach(result); 
        return result;
    }
}

補足

今回の要件では、登録されている User オブジェクトの洗い替えを実行したいために、登録対象の User オブジェクトを削除するため、
上記のメソッドを実行しています。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2