]
Chris Wilson commented on HHH-2007:
-----------------------------------
It would be pretty crazy for Hibernate to try to enforce this on the client end. What
would it do if someone else inserted data into the database that Hibernate considers
valid? Should Hibernate always perform a SELECT to look for duplicate values before
allowing you to INSERT or UPDATE a record?
This should be enforced by the DBMS. I don't understand why you don't want it to
be.
A UNIQUE constraint on the FK reference would normally be the correct solution in your
case, as you don't want to share PKs. ANN-258 shows that this works for all databases
except Derby. This is a limitation of Derby, not Hibernate.
Case closed IMHO.
Hibernate doesn't support optional one-to-one associations
----------------------------------------------------------
Key: HHH-2007
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2007
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects 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: