[hibernate-issues] [Hibernate-JIRA] Created: (HHH-2007) Hibernate doesn't support optional one-to-one associations

Andrei Iltchenko (JIRA) noreply at atlassian.com
Wed Aug 16 08:37:19 EDT 2006


Hibernate doesn't support optional one-to-one associations
----------------------------------------------------------

         Key: HHH-2007
         URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2007
     Project: Hibernate3
        Type: Bug

  Components: core  
    Versions: 3.2.0.cr2    
    Reporter: Andrei Iltchenko


Hibernate doesn't properly support optional one-to-one associations, e.g. Person (0..1) -- (0..1) Passport. 

The Hibernate books and reference all talk of two ways of mapping one-to-one associations: 
1. using a many-to-one fk association with a unique constraint on the fk; 
2. using a pk association. 

the trouble with both of them is that they enforce the mandatory property of an association end, which sometimes is not desirable. The first way enforces the mandatory property with the uniqueness constraint on the fk, the other by using the fact that one table's pk is its fk. 

I tried to see if I could adapt the 1st way of representing one-to-ones to 
support optional association ends. What I did was simply remove the unique and not null constrains from DDL generated (without removing it it would be impossible to have a Person record that doesn't reference a Passport record): 

from 
CREATE TABLE Person ( 
PassUniqueId                   VARCHAR (32)                NOT NULL, 
version                        INTEGER                       NOT NULL, 
uniqueId                       VARCHAR (32)                   NOT NULL, 
name                           VARCHAR (40)                   NULL, 
PRIMARY KEY (uniqueId), 
UNIQUE(PassUniqueId), 
FOREIGN KEY (PassUniqueId) REFERENCES Passport (uniqueId) 
); 

to 
CREATE TABLE Person ( 
PassUniqueId                   VARCHAR (32)                NULL, 
version                        INTEGER                       NOT NULL, 
uniqueId                       VARCHAR (32)                   NOT NULL, 
name                           VARCHAR (40)                   NULL, 
PRIMARY KEY (uniqueId), 
FOREIGN KEY (PassUniqueId) REFERENCES Passport (uniqueId) 
); 


but leave the uniqueness attribute in the mapping file: 
        <many-to-one 
            name="pass" 
            class="application.business.logic.Passport" 
            cascade="save-update,merge" 
            unique="true" 
        > 
            <column name="PassUniqueId"/> 
        </many-to-one> 


The resulting solution worked fine and I was able to create instances of Person not linked to a Passport. However Hibernate didn't succed in keeping the association from degrading into a many-to-one. It enabled me to create two Persons linked with the same Passport: 

 PASSUNIQUEID    | VIRSION | UNIQUEID    | Name 
================================================ 
 0d8b3919fffff   | 1       | 0d5fb1dcfff | John 
 0d8b3919fffff   | 0       | 10fd07bdfff | Sam 


A subsequent attempt at retrieving such Persons with Hibernate failed: 
org.hibernate.HibernateException: More than one row with the given identifier was found: 0d8b3919ffffffd60151e135b6da0164, for class: application.business.logic.Passport. 

Hibernate should be able to impose the single end property of such associations without relying on the underlying RDBMS engine and never allow them to degrade to many-to-ones.




-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira




More information about the hibernate-issues mailing list