There is a distinction between optional=true and @NotFound

I have had a few discussions with Gail on 
https://hibernate.onjira.com/browse/HHH-4982 and 
https://hibernate.onjira.com/browse/ANN-725
Don't spend too much time on these issue reports, they are very confusing.

The question boils down to whether or not @OneToOne(optional=true) 
@PrimaryKeyJoinColumn is legal what the implication is on  FK constraint 
generation and inner vs outer join use to load the object.

Let's take the simple @ManyToOne example

    @ManyToOne(optional=true) @JoinColumn(name="profile_fk") 
    @NotFound(IGNORE)
    Profile getProfile() { ... };

optional = true means that there may or may not be a Profile ie that profile_fk 
is nullable
@NotFound(IGNORE) means that if profile_fk points to a profile that is not 
present in the Profile table (say the fk = "emmanuel" and there is no profile 
with "emmanuel" as a PK).

@NotFound(IGNORE) is here to make Hibernate work on *broken* databases where 
the DBA was smart enough to decide FK constraints are useless.

This one is easy.

Now for true one to one these two concepts mix in

    @Entity
    class User {
        @Id String username;

        @OneToOne(optional=true) @PrimaryKeyJoinColumn
        Profile getProfile() { ... };
    }

In this case, a User "emmanuel" has a profile whose primary key is "emmanuel": 
the PK of User is also a foreign key pointing to profile.

Now it's perfectly reasonable to imagine that a User has no Profile in which 
case, the User PK which is also the FK to profile would point to a non existent 
entry in Profile. That would mean that we cannot enforce the foreign key 
constraint.

I think that for generated ids (via "foreign" or via derived identity), we 
cannot have optional values. That would defeat the purpose of the generator. In 
these case we should ignore optional=true (and log a warning).

For ids that are not generated, I'm torn. I see the use case above as a decent 
use case for which we would not do to outer joins instead of inner joins.
I think that the Hibernate engine reacts properly with the following mapping

    @Entity
    class User {
        @Id String username;

        @OneToOne(optional=true) @PrimaryKeyJoinColumn
        @NotFound(IGNORE)
        Profile getProfile() { ... };
    }

so we could make @NotFound(IGNORE) implicit when @OneToOne(optional=true) 
@PrimaryKeyJoinColumn is found.

Emmanuel
_______________________________________________
hibernate-dev mailing list
hibernate-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/hibernate-dev

Reply via email to