2

I have to map a large enterprise database schema. As a number of legacy applications are depending on that schema I can't change it from composite keys to surrogate keys (other than using views with instead-of triggers for ~70% of database objects) which led me to a number of issues I don't know how to overcome.

  1. How to map tables that have a surrogate (primary, auto-increment) key and a composite unique key to which a number of tables form a many-to-one relation over the surrogate key, and at the same time a number of legacy tables relate over the composite unique?
  2. What to do when several relationships over composite keys share the same component (Naselja: Korisnik/Opcina, Korisnik/Grad)? Hibernate tells me I can't use the same column (Korisnik) twice, unless I add 'updatable = false, insertable = false' to the @JoinColumn annotation. Yet when I do that, I get the message that all components of the relation have to have the same settings for insertable and updatable. How do I ever update or insert the second relation then?
  3. Inserting a row into 'Ulice' table will give me a error "org.hibernate.AnnotationException: referencedColumnNames(Korisnik, Naselje) of lc.data.hibernate.Ulice.naselja referencing lc.data.hibernate.Naselja not mapped to a single property" unless in 'Naselja' table I explicitly add a many-to-one relation to 'Korisnici' table in the model, which doesn't reflect the actual database schema.

From what I've read so far JPA doesn't support relationships to non-primary keys, but people still do it. Also my second problem might be solved with Hibernate 5, but I'm hoping for some good advice what route to take here.

Test model, database scripts and projects:


Database schema MSSQL

MSSQL create database scripts

Java NetBeans example projects

Community
  • 1
  • 1
Vedran
  • 10,369
  • 5
  • 50
  • 57
  • One idea I had, is putting updatable=false, insertable=false on all Hibernate relations, explicitly mapping every field in the table and handling the relations manually... It works, but it seems very wrong :) – Vedran May 14 '12 at 10:21

1 Answers1

2

1) - map the autoincrementing columns as primary key - create classes for the compositeid and map the many-to-one with property-ref

    <component name="compIdProperty" unique="true">
      <property column="naselje" />
      <many-to-one column="korisnik" class="Korisnik"/>
    </component>

    <many-to-one name="Naselja" property-ref="compIdProperty">
      <column name="naselje" />
      <column name="korisnik" />
    </many-to-one>

2) AFAIK it is not possible at all using hibernate

only possible way i see is to map (Grad, Opcina) as properties and manage the association yourself

3) since this is a legacy schema i would go the compromise of adding the many-to-one and also map the many-to-one to Korisnik in Opcine and Gradovi

Firo
  • 30,626
  • 4
  • 55
  • 94
  • So if I manage associations manually that way, are there any Hibernate gotchas I should be aware of? – Vedran May 14 '12 at 14:38
  • on the things Hibernate does not know of, it can not interfere. – Firo May 14 '12 at 15:01
  • I've now found that all fetching is forced to eager when mapped like this; Any way to avoid this behavior? – Vedran May 15 '12 at 13:02
  • other than don't mapping the association and manage by hand no because NH needs the identity of the referenced object which is not present when using property-ref – Firo May 15 '12 at 13:28