1

我有非常具体的情况,并尝试了不同的场景来实现从 java 集合中删除时从 DB 中删除。

我有 House 与 OneToMany 与 Room 有关系,Room 与 OneToMany 与 Bed 有关系。但 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 的任何解决方案 - 但找不到任何对我的情况有帮助的解决方案。

4

1 回答 1

0

不幸的是,当实体(实体列表)有多个父母时,就会出现某种冲突。

我什orphanRemoval至删除了标志并尝试手动删除孩子(在我的例子中是床)

entityManager.remove(床);

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

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

于 2013-06-17T16:36:29.563 回答