1

I was reading the doc of Hibernate Reactive and I encountered this statement:

"In Hibernate Reactive, on the other hand, lazy association fetching is an asynchronous process that produces a result via a CompletionStage (or Uni). Therefore, lazy fetching is an explicit operation ..."

I probably have some lack of knowledge that keep me away from understanding the meaning of the statement. Why the fact that the lazy association fetching is an async process, cause it to not be transparent like in standard Hibernate? What is the challenge or the impediment here?

From the example in the doc:

session.find(Author.class, author.id)
       .chain( author -> Mutiny.fetch(author.books) )
       .invoke( books -> ... ) 

why we have to explicitly chain the fetch method to declare that, at some point, the application may need to load the books from the DB? Standard Hibernate don't need it.

Please, make you answer as less vague than possible. I'd like to deeply understand this problem.

Thank you!

1 Answer 1

2

Because in HR, every interaction with the database (including lazy fetching) is asynchronous and so each such operation must return a special object which represents a "future" result.

The operation of fetching the author.books can't return Set<Book> because that would require synchronously fetching the collection. Instead it must return Uni<Set<Book>>.

And since we don't have a Uni<Set<Book>> in the domain model (we don't want to pollute the domain model with Uni), we use the fetch() method to map the type Set<Book> to Uni<Set<Book>>.

UPDATE:

Note that we could in principle make lazy fetching implicit if we required you to declare all your associations as type Uni. For example:

@Entity
class Author {
    @Id
    Long id;
    String name;
    @OneToMany
    Uni<List<Book>> books;
    ...
}

@Entity
class Book {
    @Id
    Long id;
    String title;
    @ManyToOne
    Uni<Author> author;
    ...
}

But, in fact, this isn't transparent at all; it leaks the type Uni into the domain model. That's actually much worse than leaking the fetch() function into code which is already dependent on Hibernate Reactive.

Because now you would not be able to reuse the domain model with regular Hibernate, nor with any other Java frameworks.

So we did not go down this path.

Sign up to request clarification or add additional context in comments.

7 Comments

"we use the fetch() method to map the type Set<Book> to Uni<Set<Book>>"... Since lazy fetching is supposed to retrieve fields when the are required, I do not understand why this mapping is not done when the, in the same way, fields are required in HR. Maybe if I can have a look at the current lazy loading algorithm it could clarify better.
I don't understand what you don't understand. Lazy fetching must be asynchronous, since it involves non-blocking IO (access to the database). Therefore, lazy fetching is an operation that must return a Uni. Since there are no Unis in the domain model, it must be an explicit operation instead of an implicit operation. That's really all you need to understand.
Why Unis, if present in the domain model, could potentially make the operation implicit? I know that lazy fetching must be async. I still not fully understand the tech limitation that avoid Mutiny.fetch(author.books) be implicit.
Sure, if you wrote all your domain classes to refer to Uni<Author> and Uni<Set<Book>>, it could be implicit. But then you could not use the domain model with plain Hibernate, nor with any other generic Java code. It would be fundamentally tied to Mutiny. (And that would be bad.)
Hibernate has its own implementation of collections which it uses to wrap java collections like List. Thanks to these wrappers lazy fetching is possible (implicitly). Why HR does not have its own implementation of collections? So a ReactiveLazyInitializable where probably forceInitialization calls the fetch() method. A ReactivePersistentList wrapper for list would contain a Uni<List> list which could stores the "result" of the fetch() method. Let me know if what I said is not clear.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.