[hibernate-dev] Is unidirectional one-to-one referencing a non-primary key valid

Steve Ebersole steve at hibernate.org
Thu Mar 8 19:13:50 EST 2018


Well now you are asking 2 different questions I think:

1) Is this a conceptually valid mapping?  Which is what you explicitly
asked originally.  I said that imo the mapping itself is conceptually valid.
2) Do we support this?  Clearly not.

More in line...


On Thu, Mar 8, 2018, 4:38 PM Gail Badner <gbadner at redhat.com> wrote:

> Hi Steve,
>
> I know that a bidirectional one-to-one association works properly with
> Product#productInfo on the "mappedBy" side, and ProductInfo#product on the
> owning side. With that mapping, ProductInfo#product is a ManyToOne that
> is a "logical" OneToOne.
>
> I agree that is the more natural way to map this association, but this use
> case is for a unidirectional one-to-one.
>

I never said that the bi-directional is the more natural mapping.  I said
that mapping the association from ProductInfo (either uni- or
bi-directionally) is more natural.


> What I'm seeing in the debugger for this unidirectional one-to-one
> association, Product#productInfo, is that it is OneToOneType with:
> * #foreignKeyType == ForeignKeyDirection.TO_PARENT
> * #referenceToPrimaryKey == true
>
> Both of these seem wrong to me for a unidirectional one-to-one, but maybe
> I'm missing something.
>
> I should mention that, in this particular case, no foreign key is
> generated. Even so, ForeignKeyDirection.TO_PARENT, means that Hibernate
> assumes that the foreign key is defined in ProductInfo, not Product,
> doesn't it? If the foreign key were in ProductInfo, then it would make
> sense that #referenceToPrimaryKey == true.
>
> I want to make sure that I understand what should be expected behavior for
> this use case.
>
> Since Product#productInfo is a unidirectional one-to-one, I would have
> expected that OneToOneType would have:
> * #foreignKeyType == ForeignKeyDirection.FROM_PARENT (with foreign key
> column Product#id)
> * #referenceToPrimaryKey == false (since it references non-PK column
> ProductInfo#productId)
>

IMO everything you say above here directly follows from Hibernate not
handling the `referencedColumnName` on `Product#productInfo`.  My guess is
that if you resolved this, the rest would fall into place, or at least get
you very close


> Also, Product#id will always be non-null, but that doesn't mean that there
> is a non-null association with ProductInfo. It seems that Hibernate should
> complain when an association cannot be found, unless the association is
> annotated with @NotFound(NotFoundAction.IGNORE).
>
> Does this sound right to you?
>

I think we want to be careful there.  But generally speaking I think that's
valid when the association is not marked optional



> Thanks,
> Gail
>
> On Thu, Mar 8, 2018 at 11:22 AM, Steve Ebersole <steve at hibernate.org>
> wrote:
>
>> For sure our model can handle this mapping, although maybe only from the
>> other side (that's generally the more natural mapping) - internally it's
>> called a "logical many-to-one".  Personally I'd say there is nothing wrong
>> with the mapping per-se.
>>
>>
>> On Wed, Mar 7, 2018 at 4:36 PM Gail Badner <gbadner at redhat.com> wrote:
>>
>>> Hi,
>>>
>>> This is an unusual mapping. My gut feeling is that it is not a valid
>>> mapping, but I don't see anything in the spec that would indicate it is
>>> invalid.
>>>
>>> Here is the mapping:
>>>
>>> @Entity
>>> public class Product {
>>>    @Id
>>>    @Column(name = "id")
>>>    private int id;
>>>
>>>    @OneToOne(cascade = CascadeType.ALL)
>>>    @JoinColumn(name = "id", referencedColumnName = "productId",
>>> insertable = false, updatable = false)
>>>    private ProductInfo productInfo;
>>>
>>> }
>>>
>>> @Entity
>>> public class ProductInfo{
>>>    @Id
>>>    private int id;
>>>
>>>    @Column(name = "productId", unique = true, updatable = false)
>>>    private int productId;
>>> }
>>>
>>> Hibernate ignores referencedColumnName = "productId" and assumes that
>>> Product and ProductInfo share the same ID value.
>>> When the IDs are not the same, Product#productInfo will be null.
>>>
>>> It seem to me that the foreign key column should be
>>> ProductInfo#productId and should reference Product#id, but this
>>> doesn't make sense
>>> for a unidirectional one-to-one owned by Product.
>>>
>>> IMO, a bidirectional @OneToOne with ProductInfo owning the association
>>> would make more sense.
>>>
>>> A test case can be found at [1]
>>>
>>> Is the mapping invalid, or is this a bug in Hibernate?
>>>
>>> Thanks,
>>> Gail
>>> [1]
>>> https://github.com/gbadner/hibernate-test-case-templates/commit/d806d4ef5cf35da85efc51ce70c5e0648ce89006
>>> _______________________________________________
>>> hibernate-dev mailing list
>>> hibernate-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>>
>>
>


More information about the hibernate-dev mailing list