One-to-many mapping // how to map legacy tables (Hibernate)

I have two old database tables that are simplified like this:

MASTER                        SLAVE
ident                         ident
sName                         sName
sNumber                       sNumber
sDesc                         sValue
-----                         ------
Java Class 'ScenarioMaster'   Java Class 'ScenarioSlave'

      

Each row has a surrogate index across the column ident

, but there is no relationship between MASTER.key

and SLAVE.key

. However, for a table, the MASTER

uniqueness of one sName / sNumber pair is true. So it will be a possible and meaningful composite key (I know it is evil).

In fact, there is a 1: n ratio, meaning that each row MASTER

refers to n rows in the table SLAVE

. Given the description of the column above, the possible population could be

MASTER                        SLAVE
100                           42
'labl'                        'labl'
1                             1
'some label'                  0.1
                              43
                             'labl'
                              1
                              0.2

      

Now using hibernate, how could I reflect this relationship in my Java classes? In ScenarioMaster

I declare a Set or List with public getters / setters like

private List<ScenarioSlave> slaves = new ArrayList<ScenarioSlave>();

      

Sleeping displays for ScenarioMaster

may contain

<bag name="slaves" cascade="all">
    <key>
        <column name="sName" not-null="true"/>
        <column name="sNumber" not-null="true"/>
    </key>
    <one-to-many class="ScenarioSlave"/>
</bag>

      

This, however, creates a strage update statement when updating is already persitant ScenarioMaster

using session.saveOrUpdate(scenarioMaster)

.

// create master scn and slave slv      
scn.addSlave(slv);  
session.saveOrUpdate(scn);

    Hibernate: 
        update
            SLAVE
        set
            sNumber=?,
            sName=?,
            sValue=?
        where
            sName=? 
            and sNumber=?
    Hibernate: 
        update
            SLAVE
        set
            sName=null,
            sNumber=null 
        where
            sName=? 
            and sNumber=?   

      

What am I doing wrong? Where does this second update come from? I think it has something to do with sName / sNumber not being a key for ScenarioSlave

. Why I can't understand.

Note that the sName / sNumber parameters point to valid values ​​and that the instance ScenarioMaster

that I want to save through saveOrUpdate

actually has an instance with a non-null ScenarioSlave

in the list slaves

.

EDIT : Composite key is deferred to a separate class using this mapping

<composite-id name="keyId" class="ScenarioKeyId">
    <key-property name="name" access="field" column="sName"
        type="string" length="20"/>
    <key-property name="number" access="field" column="sNumber"
        type="long"/>
</composite-id>

      

I really don't want to create a table NAMENUMBER_KEY

that maps "labl", 1 to something like "key_labl1", which can then be used id

to hibernate. I suppose this is what hibernate does (without using an actual table).

+1


a source to share


2 answers


Hibernation does not work with composite keys in my experience. This is one of the main problems with Hibernate as far as I've seen. I've worked in the past to avoid using "pure" compound keys; that is, I gave the composite keymaps a unique ID column that Hibernate can then disable.



+2


a source


I did a little work (must love Apache Derby ) pretending both tables did not have a composite id. Then I found out that the statement SET ... = null

is most likely issued to invalidate list members slave

.

create table MASTER(
   ident numeric(10) not null, -- key column
   name char(20) not null,
   number numeric(10) not null,
   descr char(64) not null
);

create table SLAVE(
   ident numeric(10) not null, -- key column
   name char(20) not null,
   number numeric(10)   ,      -- foreign key f. MASTER.ident
   value float not null
);

      

Here is my test code. I have set up the generator for the main class key as assigned

.

        Master master = new Master();
        master.setIdent(Integer.valueOf(0));
        master.setName("name");
        master.setNumber(42);
        master.setDescr("name/42 descr");
        Slave slv = new Slave("name", 42, 0.001);
        master.addSlave(slv);
        theSession.beginTransaction();
        theSession.saveOrUpdate(master);
        theSession.getTransaction().commit();

      



Then, by allowing the NULL

values ​​in the string SLAVE.number

, I get

Hibernate: 
    update
        SLAVE 
    set
        number=null 
    where
        number=?
Hibernate: 
    update
        SLAVE 
    set
        number=? 
    where
        ident=?

      

Now I only need to figure out how to actually remove the stale rows in slave

and then set the foreign key column to NULL

...

0


a source







All Articles