Class CreateAlteredTrackableRepositoryOverrideImpl

java.lang.Object
com.broadleafcommerce.billing.provider.jpa.repository.CreateAlteredTrackableRepositoryOverrideImpl
All Implemented Interfaces:
CreateAlteredTrackableRepositoryOverride

public class CreateAlteredTrackableRepositoryOverrideImpl extends Object implements CreateAlteredTrackableRepositoryOverride
Our normal pattern is to pre-assign primary keys, but keep the domain class id declaration using Hibernate generation in case an alternate flow is used to create. However, this has the side effect of making creates use a merge. For billing domain, we want to force creates to use entity manager persist, which will use a sql insert. The design intent is to create once and then fail with an integrity violation anywhere else where a `service`#create flow is called for the same id. To establish the "create" circumstance, we rely on either detecting the operation type on the contextInfo parameter for the save call, or detecting a null value for the Version annotated field.

Under Hibernate 7 a duplicate create no longer reaches the database insert (the tracking-entity interceptor detects the pre-existing row and marks the entity detached, so persist fails fast), so assertNotAlreadyPersisted(Trackable) detects the existing row up front and raises the DataIntegrityViolationException callers expect.

  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    applyLock(com.broadleafcommerce.data.tracking.core.Trackable managed)
     
    protected void
    assertNotAlreadyPersisted(com.broadleafcommerce.data.tracking.core.Trackable entity)
    Enforces the create-once contract: a service#create for a contextId that already exists must fail with a DataIntegrityViolationException.
    protected void
    detectVersionAttribute(com.broadleafcommerce.data.tracking.core.Trackable entity)
     
    protected <T> Optional<jakarta.persistence.metamodel.SingularAttribute<?,?>>
    findVersionAttribute(jakarta.persistence.metamodel.IdentifiableType<T> type, jakarta.persistence.metamodel.Metamodel metamodel)
     
    protected jakarta.persistence.EntityManager
     
    protected <T> boolean
    isNew(T entity)
     
    protected void
    replenishRequiredFields(com.broadleafcommerce.data.tracking.core.Trackable entity)
     
    com.broadleafcommerce.data.tracking.core.Trackable
    save(com.broadleafcommerce.data.tracking.core.Trackable entity, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Serves as override for JpaTrackableRepository.save(Trackable, ContextInfo)
    Iterable<com.broadleafcommerce.data.tracking.core.Trackable>
    saveAll(Iterable<com.broadleafcommerce.data.tracking.core.Trackable> entities, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Serves as override for JpaTrackableRepository.saveAll(Iterable, ContextInfo)
    protected void
    setTrackingContainer(com.broadleafcommerce.data.tracking.core.Trackable result)
     

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • CreateAlteredTrackableRepositoryOverrideImpl

      public CreateAlteredTrackableRepositoryOverrideImpl()
  • Method Details

    • save

      @Transactional(transactionManager="billingTransactionManager") public com.broadleafcommerce.data.tracking.core.Trackable save(com.broadleafcommerce.data.tracking.core.Trackable entity, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: CreateAlteredTrackableRepositoryOverride
      Serves as override for JpaTrackableRepository.save(Trackable, ContextInfo)
      Specified by:
      save in interface CreateAlteredTrackableRepositoryOverride
    • saveAll

      @Transactional(transactionManager="billingTransactionManager") public Iterable<com.broadleafcommerce.data.tracking.core.Trackable> saveAll(Iterable<com.broadleafcommerce.data.tracking.core.Trackable> entities, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: CreateAlteredTrackableRepositoryOverride
      Serves as override for JpaTrackableRepository.saveAll(Iterable, ContextInfo)
      Specified by:
      saveAll in interface CreateAlteredTrackableRepositoryOverride
    • assertNotAlreadyPersisted

      protected void assertNotAlreadyPersisted(com.broadleafcommerce.data.tracking.core.Trackable entity)
      Enforces the create-once contract: a service#create for a contextId that already exists must fail with a DataIntegrityViolationException.

      Historically that violation came straight from the database -- EntityManager.persist(java.lang.Object) issued an insert and the primary-key constraint rejected the duplicate. Under Hibernate 7 the insert is never reached: every tracked entity carries a tracking embeddable that injects its owner via Parent, which drives the TransientReferenceResolvingInterceptor to probe the database, find the existing row, and report the entity as detached -- so persist raises a PersistentObjectException ("Detached entity passed to persist") that Spring surfaces as an InvalidDataAccessApiUsageException rather than the integrity violation callers (e.g. the duplicate guard in DefaultPaymentProcessingService) are written to catch. We therefore detect the pre-existing row up front with the same crash-safe load-by-id the interceptor relies on and raise the expected exception ourselves.

    • replenishRequiredFields

      protected void replenishRequiredFields(com.broadleafcommerce.data.tracking.core.Trackable entity)
    • detectVersionAttribute

      protected void detectVersionAttribute(com.broadleafcommerce.data.tracking.core.Trackable entity)
    • setTrackingContainer

      protected void setTrackingContainer(com.broadleafcommerce.data.tracking.core.Trackable result)
    • applyLock

      protected void applyLock(com.broadleafcommerce.data.tracking.core.Trackable managed)
    • isNew

      protected <T> boolean isNew(T entity)
    • findVersionAttribute

      protected <T> Optional<jakarta.persistence.metamodel.SingularAttribute<?,?>> findVersionAttribute(jakarta.persistence.metamodel.IdentifiableType<T> type, jakarta.persistence.metamodel.Metamodel metamodel)
    • getEm

      protected jakarta.persistence.EntityManager getEm()