Skip to content

Different EntityManager context behavior between SimpleJpaRepository methods and derived query methods when using separate Rw/Ro EntityManagers inside a @Transactional boundaryΒ #4107

@iks15174

Description

@iks15174

🧩 Summary

When calling a RoRepository (using a read-only EntityManager) within a @transactional method that uses a Rw (read-write) EntityManager, the behavior differs depending on whether the repository method is:

A method implemented by SimpleJpaRepository (e.g., findById, getReferenceById), or

A derived query method (method-name-based JPQL generation).

This difference leads to inconsistent persistence context behavior and affects lazy loading.

Reproduction repository:
πŸ‘‰ https://github.com/iks15174/jpa-test

πŸ§ͺ Reproduction Behavior

1. Using SimpleJpaRepository methods (e.g., findById)

The entity loads successfully.

But accessing a lazy-loaded association triggers:

LazyInitializationException

This happens because the Ro EntityManager's persistence context is closed immediately after the method call.

2. Using derived query methods

The entity loads successfully.

Lazy-loaded associations work normally.

The Ro EntityManager remains active, and its persistence context participates properly.

πŸ” Observed Cause

Based on investigation, the behavior difference appears to be:

Inside an active @transactional method using the Rw EntityManager, calling a RoRepository method behaves differently depending on the type of repository method:

βœ” Case 1: SimpleJpaRepository methods

The Ro EntityManager does not join the existing transactional context.

Its persistence context is not propagated upward.

After the repository method returns, the Ro persistence context is immediately closed.

Therefore, the subsequent lazy loading fails.

βœ” Case 2: Derived query methods

The Ro EntityManager remains active after the query execution.

Lazy loading works because the Ro persistence context stays open.

This results in two different behaviors for the same RoRepository depending solely on which type of repository method is invoked.

❓ Question

I would like to understand whether this difference is intentional or unexpected.

If this behavior is intentional:

What is the design rationale behind treating SimpleJpaRepository methods and derived query methods differently in terms of persistence context lifecycle and EntityManager participation?

If this is not intentional:

Is this a candidate for improvement or unification so that both method types behave consistently?

πŸ“Ž Additional Information

Reproduction project demonstrating the issue:
πŸ”— https://github.com/iks15174/jpa-test

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions