在Hibernate中将一对多映射到子类

时间:2015-04-13 16:55:31

标签: hibernate hibernate-mapping hibernate-onetomany table-per-class

我有以下课程:

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>

我正在尝试创建一个Step,在每个列表中添加一个变量,并使用以下内容将整个结构添加到数据库中:

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中的子类?我缺少一些额外的配置吗?

1 个答案:

答案 0 :(得分:0)

  1. 为子类创建接口并让子类实现它们
  2. 在界面本身中添加@Entity @Table批注
  3. 在接口的get方法中添加@Column / @OneToMany等注释。
  4. 并使用该界面创建集合/列表/袋子。 这对我有用。