Ok I reproduce it "simply" with 3 tables:
create table table1 (ID INTEGER NOT NULL DEFAULT SERIAL)
create table table2 (ID INTEGER NOT NULL DEFAULT SERIAL, idtable1 INTEGER NOT NULL, idtable2 INTEGER NOT NULL)
create table table3 (ID INTEGER NOT NULL DEFAULT SERIAL)
alter table table2 add constraint constr unique (idtable1, idtable3)
Mapping (3 files Table1.hbm.xml, ...):
Code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.test.datamodel.Table1" table="TABLE1" schema="MYDB">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="increment" />
</id>
<set name="idtable2" inverse="true" cascade="all-delete-orphan">
<key>
<column name="idtable1" not-null="true" />
</key>
<one-to-many class="org.test.datamodel.Table2" />
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.test.datamodel.Table2" table="TABLE2" schema="MYDB">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="increment" />
</id>
<many-to-one name="idtable1" class="org.test.datamodel.Table1" fetch="select" unique-key="constr">
<column name="idtable1" not-null="true" />
</many-to-one>
<many-to-one name="idtable3" class="org.test.datamodel.Table3" fetch="select" unique-key="constr">
<column name="idtable3" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.test.datamodel.Table3" table="TABLE3" schema="MYDB">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="increment" />
</id>
<set name="idtable2" inverse="true">
<key>
<column name="idtable3" not-null="true" />
</key>
<one-to-many class="org.test.datamodel.Table2" />
</set>
</class>
</hibernate-mapping>
Bean:
Code:
package org.test.datamodel;
import java.util.Set;
public class Table1 implements java.io.Serializable {
/**
* serial version UID
*/
private static final long serialVersionUID = 1L;
// Fields
private Integer id;
private Set idtable2;
public Table1() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set getIdtable2() {
return idtable2;
}
public void setIdtable2(Set idtable2) {
this.idtable2 = idtable2;
}
}
package org.test.datamodel;
public class Table2 implements java.io.Serializable {
/**
* serial version UID
*/
private static final long serialVersionUID = 1L;
// Fields
private Integer id;
private Table1 idtable1;
private Table3 idtable3;
public Table2() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Table1 getIdtable1() {
return idtable1;
}
public void setIdtable1(Table1 idtable1) {
this.idtable1 = idtable1;
}
public Table3 getIdtable3() {
return idtable3;
}
public void setIdtable3(Table3 idtable3) {
this.idtable3 = idtable3;
}
}
package org.test.datamodel;
import java.util.Set;
public class Table3 implements java.io.Serializable {
/**
* serial version UID
*/
private static final long serialVersionUID = 1L;
// Fields
private Integer id;
private Set idtable2;
public Table3() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set getIdtable2() {
return idtable2;
}
public void setIdtable2(Set idtable2) {
this.idtable2 = idtable2;
}
}
Junit test:
Code:
public void testThat(){
Configuration cfg = new org.hibernate.cfg.Configuration();
Properties hibProp = new Properties();
try {
String url = "jdbc:sapdb://mezzo:7210/use_yja";
String user = "yja";
String password = "yja";
Class.forName("com.sap.dbtech.jdbc.DriverSapDB");
Connection connection = DriverManager.getConnection(url, user, password);
hibProp.load(new FileInputStream(new File("D:/workspaceV4/webapp/WEB-INF/classes/hibernate.properties")));
cfg = cfg.addProperties(hibProp);
SessionFactory sf = cfg.configure(new File("D:/workspaceV4/test/hibernate.cfg.xml")).buildSessionFactory();
Session session = sf.openSession(connection);
session.beginTransaction();
Table1 table1 = (Table1) session.load(Table1.class, new Integer(2));
Table2 table2 = (Table2)table1.getIdtable2().iterator().next();
//remove an object
table1.getIdtable2().remove(table2);
Table2 newTable2 = new Table2();
newTable2.setIdtable1(table2.getIdtable1());
newTable2.setIdtable3(table2.getIdtable3());
//add a new object with the same secondary key
table1.getIdtable2().add(newTable2);
table2 = null;
session.getTransaction().commit();
} catch (RuntimeException re) {
throw re;
} catch (Exception e) {
System.out.println(e.toString());
}
}
The cascade produce the following commands:
Code:
Hibernate:
select
table1x0_.ID as ID0_0_
from
MYDB.TABLE1 table1x0_
where
table1x0_.ID=?
Hibernate:
select
idtable2x0_.ID as ID1_,
idtable2x0_.ID as ID1_0_,
idtable2x0_.idtable1 as idtable2_1_0_,
idtable2x0_.idtable3 as idtable3_1_0_
from
MYDB.TABLE2 idtable2x0_
where
idtable2x0_.ID=?
Hibernate:
select
max(ID)
from
TABLE2
Hibernate:
insert
into
MYDB.TABLE2
(idtable1, idtable3, ID)
values
(?, ?, ?)
Hibernate:
delete
from
MYDB.TABLE2
where
ID=?
If the constraint is set in the data base, the insert failed.
If the delete is done before the insert, everything will be OK.
edit: I've been redirected to
http://forum.hibernate.org/viewtopic.php?t=934483 so it seems to be an old issue that the team don't want to solve for some unclear reason to me... I guess the answer to my first post is "NO".