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

Gail Badner gbadner at redhat.com
Thu Mar 8 17:38:04 EST 2018


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.

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)

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?

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