He revisado muchas publicaciones en Internet y ninguna aborda mi problema. Realmente aprecio si alguien puede ayudar! Tengo OneToMany relación padre-hijo. Hibernate no inserta en cascada el elemento secundario (Nivel 2) cuando una de las claves compuestas secundarias es la clave externa del elemento primario (Nivel 1). Especifiqué cascade = "all" y no importa que el inverso sea verdadero o falso, los resultados son los mismos. No hay excepción, y simplemente no se inserta. Debajo de la impresión, se muestra que el Nivel1 se insertó con éxito, pero el Nivel 2 solo se seleccionó, no se insertó.No hay inserción en cascada para el niño con clave externa en el padre
de hibernación: insertar en sst.level_1 (, estado nombre) valores Hibernate (?,?): Seleccionar level2x_.LEVEL_1_ID, level2x_.TIMESEGMENT, level2x_.CATEGORY como CATEGORY4_ de sst.level_2 level2x_ donde level2x_.LEVEL_1_ID =? y level2x_.TIMESEGMENT =?
Las API son Hibernate 4.1.6/Spring 3.1.2.
Aquí es la definición de la tabla de MySQL:
CREATE TABLE level_1
(
ID int NOT NULL PRIMARY KEY AUTO_INCREMENT,
STATUS int,
NAME varchar(255)
);
CREATE TABLE level_2
(
LEVEL_1_ID int,
TIMESEGMENT int,
CATEGORY varchar(2),
PRIMARY KEY (LEVEL_1_ID, TIMESEGMENT),
FOREIGN KEY (LEVEL_1_ID) REFERENCES level_1(ID) ON DELETE CASCADE
);
Aquí está el código de prueba.
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
doInsert(context);
}
private static void doInsert(ApplicationContext context) {
Level1 level1 = new Level1();
Level2 level2 = new Level2();
level1.setName("LEVEL 1 NAME");
level1.setStatus(1);
level1.getLevel2s().add(level2);
level2.setLevel1(level1);
level2.setCategory("CA");
level2.setId(new Level2Id(level1.getId(), 10));
Level1DAO level1DAO = (Level1DAO) context.getBean("Level1DAO");
level1DAO.save(level1);
}
}
Mapeo para el Nivel 1:
<hibernate-mapping>
<class name="com.jc.hibernate.Level1" table="level_1" catalog="sst">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="status" type="java.lang.Integer">
<column name="STATUS" />
</property>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<set name="level2s" inverse="true" cascade="all">
<key>
<column name="LEVEL_1_ID" not-null="true" />
</key>
<one-to-many class="com.jc.hibernate.Level2" />
</set>
</class>
</hibernate-mapping>
Mapeo para el Nivel 2:
<hibernate-mapping>
<class name="com.jc.hibernate.Level2" table="level_2" catalog="sst">
<composite-id name="id" class="com.jc.hibernate.Level2Id">
<key-property name="level1Id" type="java.lang.Integer">
<column name="LEVEL_1_ID" />
</key-property>
<key-property name="timesegment" type="java.lang.Integer">
<column name="TIMESEGMENT" />
</key-property>
</composite-id>
<many-to-one name="level1" class="com.jc.hibernate.Level1" update="false" insert="false" fetch="select">
<column name="LEVEL_1_ID" not-null="true" />
</many-to-one>
<property name="category" type="java.lang.String">
<column name="CATEGORY" length="2" />
</property>
</class>
</hibernate-mapping>
Gracias por la respuesta. Tiene sentido que el identificador de nivel 1 sea nulo, lo que causó el problema. En este caso, ¿cómo configuraría la transacción para que sea atómica para los niveles 1 y 2? – John
Ver mis actualizaciones para salvar tanto al niño como a la madre en la transacción – Shailendra