On 24 août 2011, at 23:17, Gail Badner wrote:

> @NotFound is Hibernate-specific, isn't it? Is there anything in the JPA 2 
> spec that covers this functionality?

Nope, JPA 2 does not cover this case.

> 
> Since the default for @OneToOne is optional=true, it doesn't seem right that 
> it always be implicitly applied with @PrimaryKeyJoinColumn, unless 
> optional=false is explicitly specified.  
> 

Maybe you're right but I don't have the same rightness feeling. 

Anyways, we can't rewrite history and we can differentiate not set from set to 
a value in Java's annotations. Besides, I suspect (has to be verified) that 
normal forms don't like null values even for foreign keys. This approach could 
be considered better though the proper approach would be to use a join table 
with unique constraints.

> Implicitly applying @NotFound(IGNORE) would break the default mappings for 
> unidirectional and bidirectional one-to-one relationships documented in the 
> spec.

Can you expand here. I don't follow you.

> 
> It seems reasonable that the application would need to specify 
> @NotFound(IGNORE) to get this Hibernate-specific functionality.

There is a big difference. The many to one foreign key column pointing to a non 
existent entry is definitely bad form. I am not so sure about that in the PF/FK 
case (see above).

> 
> Here is my proposal:
> 
> @OneToOne(optional=true) with @PrimaryKeyJoinColumn:
> 
>   A) ID is generated (can only be foreign???)
>      1) @OneToOne is NOT annotated with @NotFound(IGNORE)
>         - ignore optional=true and log as INFO
>         - export foreign key
>         - load using an inner join

ok, log as WARN as the user should fix it.

>      2) @OneToOne is annotated with @NotFound(IGNORE)
>         - throw an exception saying that @NotFound(IGNORE) is not allowed 
> with generated IDs
> 

ok, log as WARN

>   B) ID is not generated
>      1) @OneToOne is NOT annotated with @NotFound(IGNORE)
>         - ignore optional=true and log as INFO
>         - export foreign key
>         - load using an inner join

That's where we disagree. I would honor optional=true in this case. That's not 
a case that we encounter that often

>      2) @OneToOne is annotated with @NotFound(IGNORE)
>         - do not export foreign key
>         - load using an outer join
> 

ok, log as WARN

> @OneToOne(optional=true) with derived identity
> 
>   1) @OneToOne is NOT annotated with @NotFound(IGNORE)
>      - ignore optional=true and log as INFO
>      - export foreign key
>      - load using an inner join
> 

ok, log as WARN

>   2) @OneToOne is annotated with @NotFound(IGNORE)
>      - throw an exception saying that @NotFound(IGNORE) is not allowed with 
> derived IDs
> 

ok, log as WARN

> What do you think?
> 
> Gail
> ----- Original Message -----
> From: "Emmanuel Bernard" <emman...@hibernate.org>
> To: hibernate-dev@lists.jboss.org
> Sent: Wednesday, August 24, 2011 12:08:33 PM
> Subject: [hibernate-dev] On @OneToOne(optional=true) and      
> @PrimaryKeyJoinColumn
> 
> 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


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

Reply via email to