0
1

More than 3 years have passed since last update.

JPAで変更不可能コレクションを削除すれば当然UnsupportedOperationExceptionになる

Posted at

通常はUnsupportedOperationExceptionを目にすることはほとんど無い。変更不可能なコレクションに対してうっかりaddremoveをした場合、な程度と思われる。

なのだが、JPAでUnsupportedOperationExceptionに遭遇してしばらくハマったのでメモを残しておく。

やりたい事としては、1:Nのエンティティを永続化したあと、そのエンティティに対して子コレクションを削除する、というもの。

    @Transactional
    @Override
    public void run(String... args) throws Exception {
        Parent parent = new Parent(5L, "name", List.of(
                new Child(new ChildId(101L, 1L), "aaa", null),
                new Child(new ChildId(102L, 1L), "bbb", null)
                ));
        em.persist(parent);

        Parent parent2 = pr.getOne(5L);
        System.out.println(parent == parent2); // true
        List<Child> children = parent2.getChildren();
        parent2.getChildren().clear();
        em.persist(parent2);
    }
Caused by: java.lang.UnsupportedOperationException: null
    at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71) ~[na:na]
    at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.clear(ImmutableCollections.java:77) ~[na:na]
    at org.hibernate.collection.internal.PersistentBag.clear(PersistentBag.java:495) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]

上記コードだとparentparent2は同一インスタンスが返る。そうするとgetChildrenList.ofの変更不可能コレクションが返されるため、clearするとUnsupportedOperationExceptionになる。

実際のコードは永続化コンテキストに入れて取り出す部分が離れていたため、同一インスタンスが返ることにすぐ気付けなかった。永続化コンテキストに入れて取り出せばArrayListとかの変更可能コレクションに詰めなおされる、と無意識に思い込んでいたので、上記のようなコードだと同一インスタンスが返される、てことになかなか気付けずハマってしまった。

0
1
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
0
1