package com.ankurm.hibernatedemo.persistenceannotations; import static org.assertj.core.api.Assertions.assertThat; import com.ankurm.hibernatedemo.HibernateDemoApplication; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; /** * MixedAccessEntity has FIELD access by default (because @Id sits on a field), but one * property ("computedLabel") is explicitly switched to PROPERTY access. This proves: * (1) Hibernate really does call the getter -- not read a backing field -- to determine the * persisted value for that one property, and (2) it calls it MORE than once per flush * (dirty-check read + write), which matters if the getter has side effects or is expensive. * *

Docs: docs/05-jpa-persistence-annotations.md, Topic 2. */ @SpringBootTest(classes = HibernateDemoApplication.class) class MixedAccessTest { @Autowired private EntityManagerFactory emf; @Test void propertyAccessAttribute_getterIsCalledByHibernate_multipleTimesPerFlush() { EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); MixedAccessEntity e = new MixedAccessEntity("widget"); int callsBeforePersist = e.getGetterCallCount(); em.persist(e); em.getTransaction().commit(); Long id = e.getId(); int callsAfterFlush = e.getGetterCallCount(); em.close(); System.out.println("RESULT[mixed-access]: getComputedLabel() call count before persist=" + callsBeforePersist + ", after commit/flush=" + callsAfterFlush + " (PROPERTY-access attributes are read via the getter at flush time, not via a backing field)"); assertThat(callsAfterFlush).isGreaterThan(callsBeforePersist); EntityManager em2 = emf.createEntityManager(); Object storedLabel = em2.createNativeQuery( "select computed_label from mixed_access_entity where id = " + id).getSingleResult(); em2.close(); System.out.println("RESULT[mixed-access]: DB column computed_label = " + storedLabel); assertThat(storedLabel).isEqualTo("WIDGET"); } }