JPA - как сделать возвращаемый объект снова обычным POJO

@Override
public void run(String... args) throws Exception {

    Person person = personService.getPerson(1L);
    System.out.println(person);

    Person person1 = new Person();
    System.out.println(person1);
}

Где Person это стандартно проаннотированная model с @Entity, @Table, полями @Column и т.д. Одно из полей - коллекция с LAZY инициализацией. Так вот, в случае person1 - я получу в распечатке эту коллекцию null - никто не возмущается лейзи или нет эта коллекция. А в случае с person мы конечно же получим

org.hibernate.LazyInitializationException: failed to lazily initialize a collection

то есть , ну я плохо уже понимаю этот момент, за person еще "кто-то" следит, хотя это вроде как уже detached объект от persistence context.

Вопрос - что надо сделать с person, чтобы его sout дал просто null на коллекцию. И можете подсказать где вообще об этом можно подробно почитать

Сам сервис personService дергает метод у репозитория getPersonByIdWithoutFetch

 @Repository
public interface PersonRepository extends JpaRepository<Person,Long> {

    @Query("SELECT p FROM Person p JOIN FETCH p.roles r WHERE p.id =:personId")
    Person getPersonByIdWithFetch(Long personId);

    @Query("SELECT p FROM Person p WHERE p.id =:personId")
    Person getPersonByIdWithoutFetch(Long personId);
}

Person entity

        @Entity
    @Table(name = "persons")
    public class Person {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;

        @Column(name = "username")
        private String username;

        @Column(name = "password")
        private String password;

        @ManyToMany(cascade = {
                CascadeType.PERSIST,
                CascadeType.MERGE
        }, fetch = FetchType.LAZY)
        @JoinTable(name = "person_roles",
                joinColumns = @JoinColumn(name = "person_id"),
                inverseJoinColumns = @JoinColumn(name = "role_id")
        )
        private List<Role> roles = new ArrayList<>();
}

Ответы (2 шт):

Автор решения: Z.John

В момент когда вы делаете System.out.println(person); происходит вызов person.toString() именно в этот момент запрашивается ваше Lazy поле. Но не может проинициализироваться и возникает ошибка LazyInitializationException

Чтоб этого избежать, можно пометить метод аннотацией @Transactional, или в параметрах конфигурации задать свойство hibernate.enable_lazy_load_no_trans = true.

Есть статья на эту тему здесь https://vladmihalcea.com/the-best-way-to-handle-the-lazyinitializationexception/

→ Ссылка
Автор решения: Orthodox

После выполнения Person person = personService.getPerson(1L); объект person автоматически помещается в кэш персистности и Hibernate следит за всеми объектами, которые в нем находятся. Для того, чтобы вывести объект из кэша персистности можно сделать em.detach(person); (при этом в БД не идут никакие update и пр.) и тогда person будет вне компетенций Hibernate. Содержимое кэша можете посмотреть с помощью класса-утилиты. Функцию showSessionCaсhe8( session, 1 ) нужно вызвать до и после detach. В консоль будет выводиться также информация и о коллекции roles объекта person.

→ Ссылка