Natural Ids should be better documented or one should be able to run them more lightweight

As per comment by Gavin king moved to forum HHH-17556
So after a Hibernate update I struggle with NaturalIds.
I would like to think that using LazyFetching is good, because otherwise everything has to be fetched recursively. So one simple example:

@Entity
public class Human {
    @NaturalId
    @ManyToOne(fetch = FetchType.LAZY)
    Human mother;

    @NaturalId
    int orderBirth;
}

We can identify each human by their mother and by number of child of their mother. No two different humans can have the same mother and have the same order of Birth. Now if I ‘have’ to make ‘mother’ an eager Fetch type, it would mean that everytime I resolve any human their full ancestry has to be resolved, and I probably dont need that. Thats why we have always been using natural ids and lazy fetches.
There is nothing in the documentation that says there is a problem/its forbidden to use lazyfetches and a natural ids…

Furthermore the documentation on the cache isnt quite clear. So in the sourcecode of @NaturalId one can find the sentence:

If the entity is also marked for {@linkplain

  • NaturalIdCache natural id caching}, then these methods may be able
  • to avoid a database round trip.

I would argue thats plain wrong. Layer one cache is always active so even if you dont use NaturalIdCache hibernate will try to cache the naturalId. NaturalIDCache seems to only affect layer2 cache in some way.

So if I would have known what I know now I would simply never used @NaturalId at all ever and just sticked with UniqueConstrains, but it isnt exactly clearly documented that
A) Lazy fetching is apperantly problematic/ forbidden
B) Hibernate will try to maintain some sort of layer 1 cache and there is no way to turn that off.
And thats why I opened [HHH-17562] - Hibernate JIRA.

Obvious workaround for me would be to replace every single @NaturalId in my project with UniqueConstraints and scream at everyone who adds an entity using @NaturalID.
But I would beg of you to document the sideeffects of naturalId more clearly, especially when the documentation states:

Even if a natural id does not make a good primary key (surrogate keys being usually preferred), it’s still useful to tell Hibernate about it.

There is nothing in the documentation that says there is a problem/its forbidden to use lazyfetches and a natural ids…

Why do you think lazy fetching is forbidden? If you have a problem with lazy associations and natural ids, I’d say you hit a bug. Please try to create a reproducer with our test case template (hibernate-test-case-templates/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java at main · hibernate/hibernate-test-case-templates · GitHub) and if you are able to reproduce the issue, create a bug ticket in our issue tracker(https://hibernate.atlassian.net) and attach that reproducer.

I would argue thats plain wrong. Layer one cache is always active so even if you dont use NaturalIdCache hibernate will try to cache the naturalId. NaturalIDCache seems to only affect layer2 cache in some way.

The natural id cache is used whenever you try to find an entity by natural id i.e. through the Session.byNaturalId() API. Personally, I think that having the option to disable the natural id cache is a good thing, but then the question is, why do you use natural ids in the first place and not just unique constraints?

As stated in my first sentence: This was moved to forum as request by Gavin King. There is already a bug report and a reproducer.
Gavin claimed

You want to use lazy fetching for a natural id??? I don’t see how that makes sense at all.

We have been using this pattern since forever and where not aware that there could be any issue with that.

why do you use natural ids in the first place and not just unique constraints?

Yes that part is totally my fault. I just used naturalId because they seemed to have the same effect as as an unique constraint with less typing(because you dont need to come up with some uniequname everytime).
If there was some sort of warning or clear documentation on why you possible dont want to use @NaturalID that would be helpfull. Because currently it just states:

it’s still useful to tell Hibernate about it.

Well in my usecase it was really really not useful.

We have been using this pattern since forever and where not aware that there could be any issue with that.

I haven’t followed the full discussion, but I don’t see why it would be a problem to use lazy associations as part of natural ids.

Yes that part is totally my fault. I just used naturalId because they seemed to have the same effect as as an unique constraint with less typing(because you dont need to come up with some uniequname everytime).

IMO, the only reasonable use of @NaturalId is when you want to use the byNaturalId() API.

If there was some sort of warning or clear documentation on why you possible dont want to use @NaturalID that would be helpfull. Because currently it just states:

PRs for documentation updates are welcome. The documentation is part of the hibernate Git repository, so please go ahead and add a note or warning that you think is appropriate.