Greetings,
I have been trying to resolve the following issue for some time now and after reading through the Reference docs, JP w/ Hibernate, and searching the forums I am at a loss, so here goes...
All the tables in the database use natural keys (legacy schema - can't change this). I am trying to map a entity-value relationship and the mapping I currently have works fine when doing queries, inserts, and deletes. My problem comes when performing updates. Whenever I do an update on any portion of the model, an UPDATE command is issued for the entity table, but instead of performing approprate UPDATE/INSERT statements for any changes on the value table rows, a DELETE * and then a bunch of INSERTs are performed.
Here are some code snippets:
Table Structure:
Code:
create table APPL (
APPL_CD CHAR(2) NOT NULL
...
PRIMARY KEY (APPL_CD)
);
create table APPL_ENV (
APPL_CD CHAR(2) NOT NULL,
APPL_ENV_CD CHAR(4) NOT NULL,
...
PRIMARY KEY (APPL_CD, APPL_ENV_CD)
);
alter table APPL_ENV foreign key (APPL_CD) references APPL
on delete restrict;
Mapping documents:Code:
<class name="ApplicationProfile" table="APPL">
<composite-id name="key" class="ApplicationProfile$Key" >
<key-property name="code" column="APPL_CD" length="2"/>
</composite-id>
<property ... />
<property ... />
<!-- mapping for environments -->
<bag name="environments" table="APPL_ENV" lazy="false">
<key column="APPL_CD" />
<composite-element class="ApplicationEnvironment">
<property name="envCode" column="APPL_ENV_CD" length="4" not-null="true" />
<property ... />
<property ... />
</composite-element>
</bag>
</class>
Domain Classes:Code:
public class ApplicationProfile {
private Key key; // primary key
private Collection environments = new ArrayList(); // bag mapping
// plus more members, and appropriate getters/setters
// composite key field(s) encapsulated in separate class
public class Key {
private String code
}
}
public class ApplicationEnvironment {
private String envCode;
// plus more members, and appropriate getters/setters
}
My first attempt at mapping the relationship was actually to use a
set instead of a
bag (since the values within the sub-table should be unique) but when I change the mapping instead of doing DELETE * and the re-INSERT every row for the APPLENV table, it just tries to INSERT any changed rows rather then doing an UPDATE.
Now, since the APPL_ENV_CD column of the component table is the key I had thought of trying to use an
idbag mapping for the relationships but JB w/ Hibernate indicates that the <collection-id> field isn't accessible from the domain objects, and also you can't use <generator class="natural" />
I then considered using a
map mapping but our application requires the ability for users to add 'n' additional APPL_ENV_CD values to an existing APPL and so our interface (web based) consists of an HTML table displaying any existing APPL_ENV_CD entries (1 per row) followed by several blank rows that would allow the user to enter new APPL_ENV_CD entries. I couldn't figure out how to support populating a hash based container with 'n' blank instances that could then be populated (along with the 'key' value) on form submit. That, and it also appears from JP w/ Hibernate that the map's <map-key> column isn't available from the model, which is a requirement.
So, I'm hoping for either a pointer towards how I may be incorrectly mapping my relationship with either the
set or
bag semantics, or perhaps that I am misunderstanding the limitations on the
idbag or
map mappings and that they can in fact do what I require.
Note: I have considered using <one-to-many> instead of <component-element> but the relationship is really one where the data in the APPL_ENV table has a life-cycle tied directly to it's containing APPL.
Thanks in advance for any help.
PS: I haven't been able to use the Hibernate Tools to reverse-engineer mapping files from the existing database schema because the DB2 database that we have access to (and very little control over) is missing the required packages to support the schema extracting commands the tools use to do the reverse-engineering. Which is a MAJOR bummer, cause it would have made my like so much easier...
Hibernate version: 3.2.5
Name and version of the database you are using: DB2 v7 (on z/OS)