Как управлять поведением Session.create(Entity) через hbm.xml?

197
30 ноября 2017, 01:59

Есть 2 связанные таблицы:

CREATE TABLE IF NOT EXISTS engines (
  id    SERIAL PRIMARY KEY,
  model VARCHAR(25) UNIQUE NOT NULL,
  power INTEGER            NOT NULL
);
CREATE TABLE IF NOT EXISTS cars (
  id        SERIAL PRIMARY KEY,
  mark      VARCHAR(25) NOT NULL,
  model     VARCHAR(25) NOT NULL,
  engine_id INTEGER     NOT NULL,
  FOREIGN KEY (engine_id) REFERENCES engines (id)
);

Они связанны many-to-one. Один тип двигателя может быть использован в разных автомобилях. Моя задача сделать так, что-бы когда я добавляю Car c двигателем который уже есть в таблице engines, то добавлялся новый автомобиль с соответствующим engine_id. И только если такого двигателя пока нет, добавлялся и двигатель. Но пока получается что Hibernate пытается добавлять двигатель не проверяя есть ли он в engines и я получаю:

ERROR: duplicate key value violates unique constraint "engines_model_key" Detail: Key (model)=(test) already exists.

Что понятно, так как я сам поставил model VARCHAR(25) UNIQUE в engines.

Вот мои hbm.xml:

Автомобиль:

<hibernate-mapping xmlns="http://www.hibernate.org/xsd/hibernate-mapping">
    <class name="ru.javavision.model.Car" table="cars">
        <id name="id" column="id">
            <generator class="identity"/>
        </id>
        <property name="mark" column="mark"/>
        <property name="model" column="model"/>
        <!--Прикрепляем сущьность двигателя-->
        <many-to-one name="engine" column="engine_id"
                     class="ru.javavision.model.Engine"
                     cascade="save-update" not-null="true"/>
    </class>
</hibernate-mapping>

Двигатель:

<hibernate-mapping xmlns="http://www.hibernate.org/xsd/hibernate-mapping">
    <class name="ru.javavision.model.Engine" table="engines">
        <id name = "id" type = "int" column = "id">
            <generator class="identity"/>
        </id>
        <property name="model" column="model"/>
        <property name="power" column="power"/>
    </class>
</hibernate-mapping>

Запросы к базе я делаю через SessionFactory:

private final SessionFactory factory = ...;
public void create(@NotNull final Car car) {
    try (final Session session = factory.openSession()) {
        session.beginTransaction();
        session.save(car);
        session.getTransaction().commit();
    }
}

Вопрос в следующем: могу ли я не меняя session.save(car) только за счет конфигурации в <many-to-one name="engine" column="engine_id" class="ru.javavision.model.Engine" cascade="save-update" not-null="true"/> или изменив только hbm.xml конфигурации настроить нужное мне поведение. Если да то как. Вероятно мне нужно поменять cascade="save-update" но метод тыка пока ничего не дал.

Буду признателен за любую помощь. Спасибо.

READ ALSO
Шифрование текста

Шифрование текста

Подскажите, есть ли лучшее решение для шифрования строки?

238
Что прописать в Gradle для push уведомлений?

Что прописать в Gradle для push уведомлений?

Хотел разобраться с push уведомлениямиНашел информацию, что нужно в builg

243
Передача данных из DialogFragment в Activity

Передача данных из DialogFragment в Activity

Появилась необходимость в текстовое окно установить датуметод showDialog(DIALOG_DATE) уже устарел

228