Hibernate не может удалить дочернюю запись - PullRequest
0 голосов
/ 20 мая 2018

Я не могу удалить дочернюю запись, пока обновляю (не удаляю) родительскую запись.Кроме того, я читал другие посты, но кажется, что большинство других используют аннотации, а не xml, поэтому трудно понять, как они связаны с моей проблемой.

У меня есть две таблицы: EventInfoтаблица, содержащая информацию о событиях, а затем таблица EventLicenseType, в которой имеет только два столбца, и оба этих столбца составляют первичный ключ ;один из столбцов в таблице EventLicenseType является внешним ключом таблицы EventInfo.

Проблема в том, что я не могу удалить запись EventLicenseType.Я пробовал кучу разных вещей, и ничего не работает для меня.Похоже, что hibernate хочет поставить ноль в качестве столбца eventinfoId, что, конечно, не работает.Я попытался очистить Set и затем выполнить слияние, а также специально вызвать session.delete (eventlicenseTypeRec) и затем выполнить слияние.Ни один не работает для меня.

Файл EventInfo.hbm.xml:

<hibernate-mapping default-lazy="true">

<class name="Eventinfo" table="PA_EVENTINFO">
    <id name="eventInfoId" type="int"
        column="PA_EVENTINFOID">
        <generator class="native" />
    </id>
    <property name="eventTypeId" type="java.lang.String"
        column="PA_EVENTTYPEID" length="255" />

        ...Other columns not shown here for brevity...

    <set name="eventLicenceTypeIds" lazy="false" cascade="all-delete-orphan">
        <key column="PA_EVENTINFOID"/>
        <one-to-many class="EventLicenseType" />
    </set>      
</class>

Файл EventLicenseType.hbm.xml:

<hibernate-mapping default-lazy="true">

<class name="EventLicenseType" table="PA_EVENTLICENSETYPE">
    <composite-id>
        <key-property name="licenseTypeId" type="java.lang.Integer" column="PA_LICENSETYPE"/>
        <key-property name="eventInfoId" type="java.lang.Integer" column="PA_EVENTINFOID"/>
    </composite-id>
</class>

Вот класс EventInfo.Опять же, в самом файле есть больше полей, это только важные части:

public class Eventinfo implements Serializable {
     /** identifier field */
    private int eventInfoId;    

    /** nullable persistent field */
    @Field(name="eventInfo_eventTypeId")
    private String eventTypeId;

    @IndexedEmbedded
    private Set<EventLicenseType> eventLicenceTypeIds;

    /** default constructor */
    public Eventinfo() {}

    public int getEventInfoId() {
        return this.eventInfoId;
    }

    public void setEventInfoId(int eventInfoId) {
        this.eventInfoId = eventInfoId;
    }

    public String getEventTypeId() {
        return this.eventTypeId;
    }

    public void setEventTypeId(String eventTypeId) {
        this.eventTypeId = eventTypeId;
    }

    public Set<EventLicenseType> getEventLicenceTypeIds() {
        return eventLicenceTypeIds;
    }

    public void setEventLicenceTypeIds(Set<EventLicenseType> eventLicenceTypeIds) {
        this.eventLicenceTypeIds = eventLicenceTypeIds;
    }

Вот класс EventLicenseType

public class EventLicenseType implements Serializable{

    @Field
    private int licenseTypeId;
    private int eventInfoId;

    public int getLicenseTypeId() {
        return licenseTypeId;
    }

    public void setLicenseTypeId(int licenseTypeId) {
        this.licenseTypeId = licenseTypeId;
    }

    public int getEventInfoId() {
        return eventInfoId;
    }

    public void setEventInfoId(int eventInfoId) {
        this.eventInfoId = eventInfoId;
    }
}

Вот метод, который я выполняю вмой DAO.На данный момент существует только одна запись, связанная с записью eventInfo, поэтому я просто пытаюсь выяснить, могу ли я удалить эту.(Также обратите внимание, что eventinfo определен в методе, который его окружает).

public Eventinfo execute(Session session) throws Exception {

    //Get the existing eventInfo record                 
    Eventinfo existing = (Eventinfo)session.get(Eventinfo.class, eventinfo.getEventInfoId());
    Iterator iter = existing.getEventLicenceTypeIds().iterator();
    if (iter.hasNext()) {
        EventLicenseType license = (EventLicenseType) iter.next();
        iter.remove();
        session.delete(license);
    }

    session.flush();

    return (Eventinfo) session.merge(eventinfo);
}

В приведенной выше строке session.flush () я получаю сообщение об ошибке: java.sql.BatchUpdateException: Невозможно вставить значениеNULL в столбце «PA_EVENTINFOID», таблица «PA_EVENTLICENSETYPE»;столбец не допускает пустых значений.ОБНОВЛЕНИЕ не удается.Это показывает, что hibernate пытается сделать:

update PA_EVENTLICENSETYPE set PA_EVENTINFOID=null where PA_EVENTINFOID=?

Почему он не может просто удалить запись?Почему он пытается сделать обновление?Я также попытался изменить код на приведенный ниже и получил ту же ошибку.

public Eventinfo execute(Session session) throws Exception {

    //Clear out the list
    eventinfo.getEventLicenceTypeIds().clear();             

    return (Eventinfo) session.merge(eventinfo);
}

Может кто-нибудь помочь мне с тем, что мне не хватает, или указать мне правильное направление?

1 Ответ

0 голосов
/ 20 мая 2018

Вы должны увидеть, является ли отображение между двумя таблицами односторонним или двусторонним.По сути, вам нужно рассматривать строки двух таблиц как объекты и обрезать все связи между объектами таблиц EventInfo и EventLicenceType.Поэтому, если отношение только из EventInfo -> EventLicenseType, вам нужно установить значение EventLicenseType, равное нулю, в объекте EventInfo.Также, если есть сопоставление из EventLicenseType, вам нужно установить значение присоединяющегося столбца в null.Затем merge () объект EventInfo.

Не требуется для явного удаления или удаления объекта EventLicenseType.Если здесь нет ссылок на объект EventLicenseType, JVM будет собирать его как мусор.

Надеюсь, что это решит вашу проблему.

...