JPA orphanRemoval = true尝试更新不删除

时间:2013-06-13 05:13:16

标签: java hibernate jpa

我有非常具体的情况,尝试了不同的场景,以便在从java集合中删除时从数据库中删除。

我的房子与OneToMany关系到房间和房间,与OneToMany关系到床。但是House和Bed之间也存在着OneToMany的关系:

众议院实体

public class HouHouse implements EntityInt, Serializable {
    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HOU_HOUSES_SEQ")
    private Long id;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "house", cascade = CascadeType.ALL, orphanRemoval = true)
    @OrderBy("id")
    private List<HouRoom> rooms;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "id_house")
    @OrderBy("id")
    private List<HouBed> beds;
...
}

房间实体

public class HouRoom implements EntityInt, Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HOU_ROOMS_SEQ")
    private Long id;

    @NotNull
    @ManyToOne
    @JoinColumn(name = "id_house", nullable = false)
    private HouHouse house;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name="ID_ROOM")
    @OrderBy("id")
    private List<HouBed> beds;
}

床实体

public class HouBed implements EntityInt, Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HOU_BEDS_SEQ")
    private Long id;

    @NotNull
    @ManyToOne
    @JoinColumn(name = "id_room", nullable = false)
    private HouRoom room;

    @NotNull
    @ManyToOne
    @JoinColumn(name = "id_house", nullable = false)
    private HouHouse house;
}

在我尝试这样做的情况下:

room.getBeds().remove(bed);
entityManager.merge(room);
entityManager.flush();

我收到错误:

06:28:53,344 INFO  [stdout] (http-localhost/127.0.0.1:8080-4) Hibernate: 
06:28:53,344 INFO  [stdout] (http-localhost/127.0.0.1:8080-4)     update
06:28:53,345 INFO  [stdout] (http-localhost/127.0.0.1:8080-4)         public.HOU_BEDS 
06:28:53,345 INFO  [stdout] (http-localhost/127.0.0.1:8080-4)     set
06:28:53,345 INFO  [stdout] (http-localhost/127.0.0.1:8080-4)         ID_ROOM=null 
06:28:53,345 INFO  [stdout] (http-localhost/127.0.0.1:8080-4)     where
06:28:53,345 INFO  [stdout] (http-localhost/127.0.0.1:8080-4)         ID_ROOM=? 
06:28:53,345 INFO  [stdout] (http-localhost/127.0.0.1:8080-4)         and id=?

06:28:53,346 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost/127.0.0.1:8080-4) SQL Error: 0, SQLState: 23502
06:28:53,346 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost/127.0.0.1:8080-4) Zadanie wsadowe 0 update public.HOU_BEDS set ID_ROOM=null where ID_ROOM='20' and id='32' zostało przerwane. Wywołaj getNextException by poznać przyczynę.
06:28:53,346 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost/127.0.0.1:8080-4) SQL Error: 0, SQLState: 23502
06:28:53,346 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost/127.0.0.1:8080-4) ERROR: null value in column "id_room" violates not-null constraint
06:28:53,346 ERROR [org.hibernate.engine.jdbc.batch.internal.BatchingBatch] (http-localhost/127.0.0.1:8080-4) HHH000315: Exception executing batch [could not perform addBatch]
06:28:53,346 INFO  [com.i4u.qla.action.house.HouRoomCrud] (http-localhost/127.0.0.1:8080-4) Start info here: ERROR: null value in column "id_room" violates not-null constraint
06:28:53,348 ERROR [stderr] (http-localhost/127.0.0.1:8080-4) javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.

所以 - jpa尝试更新非空字段,而不仅仅是删除行。

第二种情况 - 如果我将房间实体和床铺关系更改为双向,那么在尝试从床铺集合中移除元素并合并房间后,什么都不做。 Hibernate不会尝试删除或更新床:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy="room")
@OrderBy("id")
private List<HouBed> beds;

如何管理它有效?请帮忙。我花了很多时间尝试StackOverflow的任何解决方案 - 但找不到任何可以帮助我的情况。

1 个答案:

答案 0 :(得分:0)

当实体(实体列表)有多个父母时,不幸的是存在某种冲突。

我甚至删除了orphanRemoval标记并尝试通过

手动删除子项(在我的示例中为bed)
  

entityManager.remove(床);

也没有成功。 JPA没有尝试删除也不更新它。

所以最后我删除了房子和床之间的OneToMany关系,只留下房间和床之间,房间和房间之间的关系OneToMany - 一切都开始工作(有很多“和”,我知道,对不起)