Class TransientReferenceResolvingInterceptor

java.lang.Object
com.broadleafcommerce.common.jpa.interceptor.TransientReferenceResolvingInterceptor
All Implemented Interfaces:
Serializable, org.hibernate.Interceptor

public class TransientReferenceResolvingInterceptor extends Object implements org.hibernate.Interceptor, Serializable
A low-level Hibernate interceptor that detects detached or transient entity references containing an ID within a parent entity being saved or updated.

When found, it automatically resolves and replaces the transient entity reference with an active, managed reference (proxy) from the current persistence context to avoid TransientPropertyValueException.

See Also:
  • Constructor Summary

    Constructors
    Constructor
    Description
    TransientReferenceResolvingInterceptor(org.springframework.beans.factory.ObjectProvider<jakarta.persistence.EntityManagerFactory> entityManagerFactoryProvider)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    Distinguishes transient (new) from detached (already persisted) entities without using Hibernate's getDatabaseSnapshot() fallback.
    boolean
    onFlushDirty(Object entity, Object id, Object[] currentState, Object[] previousState, String[] propertyNames, org.hibernate.type.Type[] types)
     
    boolean
    onPersist(Object entity, Object id, Object[] state, String[] propertyNames, org.hibernate.type.Type[] types)
     
    boolean
    onSave(Object entity, Object id, Object[] state, String[] propertyNames, org.hibernate.type.Type[] types)
     

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface org.hibernate.Interceptor

    afterTransactionBegin, afterTransactionCompletion, beforeTransactionCompletion, findDirty, getEntity, getEntityName, instantiate, instantiate, onCollectionRecreate, onCollectionRemove, onCollectionUpdate, onDelete, onDelete, onInsert, onLoad, onRemove, onUpdate, onUpsert, postFlush, postMerge, preFlush, preMerge
  • Constructor Details

    • TransientReferenceResolvingInterceptor

      public TransientReferenceResolvingInterceptor(org.springframework.beans.factory.ObjectProvider<jakarta.persistence.EntityManagerFactory> entityManagerFactoryProvider)
  • Method Details

    • isTransient

      public Boolean isTransient(Object entity)
      Distinguishes transient (new) from detached (already persisted) entities without using Hibernate's getDatabaseSnapshot() fallback.

      Under Hibernate 7 that snapshot load builds an embeddable result with no owning entity initializer, so any @Parent parent-injection embeddable -- such as the tracking embeddable present on every tracked entity -- fails with "Injection of parent instance into embeddable result is not possible". Hibernate reaches that path when checking whether an assigned-id @ManyToOne reference is transient before an insert. By answering definitively here (using a normal, snapshot-safe load-by-id), Hibernate never falls through to the crashing snapshot query.

      Specified by:
      isTransient in interface org.hibernate.Interceptor
      Returns:
      FALSE if the entity already exists (managed or found in the database), TRUE if it is brand new, or null to defer to Hibernate's default when this interceptor cannot make a determination.
    • onSave

      public boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, org.hibernate.type.Type[] types)
      Specified by:
      onSave in interface org.hibernate.Interceptor
    • onPersist

      public boolean onPersist(Object entity, Object id, Object[] state, String[] propertyNames, org.hibernate.type.Type[] types)
      Specified by:
      onPersist in interface org.hibernate.Interceptor
    • onFlushDirty

      public boolean onFlushDirty(Object entity, Object id, Object[] currentState, Object[] previousState, String[] propertyNames, org.hibernate.type.Type[] types)
      Specified by:
      onFlushDirty in interface org.hibernate.Interceptor