Отображение один-ко-многим в подкласс в Hibernate
У меня есть следующие классы:
public class Step {
private int id;
private String name;
private List<CreatedVariable> createdVariables;
private List<CaptureVariable> captureVariables;
}
public abstract class Variable implements Serializable {
protected int id;
protected String name;
}
public abstract class CaptureVariable extends Variable {
}
public abstract class CreatedVariable extends Variable {
}
public class FixedValueVariable extends CreatedVariable {
private String value;
}
public class RegExVariable extends CaptureVariable {
private String regex;
}
Сценарий базы данных:
CREATE TABLE PUBLIC.STEP (
STEP_ID INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1),
STEP_NAME VARCHAR(50) NOT NULL,
CONSTRAINT STEP_PK PRIMARY KEY(STEP_ID),
CONSTRAINT STEP_UK UNIQUE(STEP_NAME)
);
CREATE TABLE PUBLIC.VARIABLE (
VARI_ID INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1),
VARI_FK_STEP_ID INTEGER NOT NULL,
VARI_ORDER INTEGER NOT NULL,
VARI_NAME VARCHAR(255) NOT NULL,
CONSTRAINT VARIABLE_PK PRIMARY KEY (VARI_ID),
CONSTRAINT VARIABLE_UK UNIQUE(VARI_FK_STEP_ID, VARI_ORDER),
CONSTRAINT VARIABLE_STEP_FK FOREIGN KEY(VARI_FK_STEP_ID) REFERENCES STEP(STEP_ID)
);
CREATE TABLE PUBLIC.CREATED_VARIABLE (
CRVA_FK_VARI_ID INTEGER NOT NULL,
CONSTRAINT CREATED_VARIABLE_PK PRIMARY KEY (CRVA_FK_VARI_ID),
CONSTRAINT CREATED_VARIABLE_VARIABLE_FK FOREIGN KEY(CRVA_FK_VARI_ID) REFERENCES VARIABLE(VARI_ID)
);
CREATE TABLE PUBLIC.CAPTURED_VARIABLE (
CAVA_FK_VARI_ID INTEGER NOT NULL,
CONSTRAINT CAPTURED_VARIABLE_PK PRIMARY KEY (CAVA_FK_VARI_ID),
CONSTRAINT CAPTURED_VARIABLE_VARIABLE_FK FOREIGN KEY(CAVA_FK_VARI_ID) REFERENCES VARIABLE(VARI_ID)
);
CREATE TABLE PUBLIC.FIXED_VALUE_VARIABLE (
FVVA_FK_VARI_ID INTEGER NOT NULL,
FVVA_VALUE VARCHAR(255) NOT NULL,
CONSTRAINT FIXED_VALUE_VARIABLE_PK PRIMARY KEY (FVVA_FK_VARI_ID),
CONSTRAINT FIXED_VALUE_VARIABLE_VARIABLE_FK FOREIGN KEY(FVVA_FK_VARI_ID) REFERENCES VARIABLE(VARI_ID)
);
CREATE TABLE PUBLIC.REGEX_VARIABLE (
RGVA_FK_VARI_ID INTEGER NOT NULL,
RGVA_REGEX VARCHAR(255) NOT NULL,
CONSTRAINT VARIAVEL_REGEX_PK PRIMARY KEY (RGVA_FK_VARI_ID),
CONSTRAINT VARIAVEL_REGEX_VARIABLE_FK FOREIGN KEY(RGVA_FK_VARI_ID) REFERENCES VARIABLE(VARI_ID)
);
Файл сопоставления xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-access="field">
<class name="br.com.edeploy.watcher.step.Step" table="STEP">
<id name="id" column="STEP_ID" type="int">
<generator class="native"/>
</id>
<property name="name" column="STEP_NAME" not-null="true"/>
<list name="createdVariables" table="VARIABLE" cascade="all" inverse="false">
<key column="VARI_FK_STEP_ID" not-null="true"/>
<list-index column="VARI_ORDER"/>
<one-to-many class="br.com.edeploy.watcher.variable.Variable" />
</list>
</class>
<class name="br.com.edeploy.watcher.variable.Variable" table="VARIABLE">
<id name="id" column="VARI_ID" type="int">
<generator class="native"/>
</id>
<property name="name" column="VARI_NAME" type="string"/>
<joined-subclass name="br.com.edeploy.watcher.variable.CaptureVariable" table="CAPTURED_VARIABLE">
<key column="CAVA_FK_VARI_ID"/>
<joined-subclass name="br.com.edeploy.watcher.variable.RegExVariable" table="REGEX_VARIABLE">
<key column="RGVA_FK_VARI_ID"/>
<property name="regex" column="RGVA_REGEX" type="string"/>
</joined-subclass>
</joined-subclass>
<joined-subclass name="br.com.edeploy.watcher.variable.CreatedVariable" table="CREATED_VARIABLE">
<key column="CRVA_FK_VARI_ID"/>
<joined-subclass name="br.com.edeploy.watcher.variable.FixedValueVariable" table="FIXED_VALUE_VARIABLE">
<key column="FVVA_FK_VARI_ID"/>
<property name="value" column="FVVA_VALUE" type="string"/>
</joined-subclass>
</joined-subclass>
</class>
</hibernate-mapping>
Я пытаюсь создать Шаг, добавить одну переменную в каждый список и добавить всю структуру в базу данных с помощью следующего:
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory = configuration
.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
session.beginTransaction();
Step step = new Step("step1");
RegExVariable regExVariable = new RegExVariable("regVariable", ".");
step.getCaptureVariables().add(regExVariable);
FixedValueVariable fixedValueVariable = new FixedValueVariable("fixedValueVariable", "value");
step.getCreatedVariables().add(fixedValueVariable);
session.save(step);
session.getTransaction().commit();
session.close();
sessionFactory.close();
Но hibernate генерирует следующий SQL для вставки в таблицу VARIABLE:
Hibernate:
insert
into
VARIABLE
(VARI_ID, VARI_NAME)
values
(default, ?)
13:36:56.209 [main] DEBUG o.h.e.jdbc.spi.SqlExceptionHelper - could not execute statement [n/a]
java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: NOT NULL check constraint; SYS_CT_10390 table: VARIABLE column: VARI_FK_STEP_ID
Если я создаю только один список с классом Variable, я могу вставить, и Hibernate генерирует все SQL правильно для вставки во все 5 таблиц.
Можно ли сопоставить список (один ко многим) с подклассом в Hibernate? Есть ли какая-то дополнительная конфигурация, которую мне не хватает?
0 ответов
- Создайте интерфейс для подклассов и сделайте так, чтобы подклассы реализовали их
- Добавьте аннотации @Entity @Table к самому интерфейсу
- Добавьте аннотации @Column / @OneToMany и т. Д. В методы get интерфейса.
- И используйте интерфейс для создания набора / списка / сумки. Это сработало для меня.