Class JpaTransactionManagerImpl
- All Implemented Interfaces:
JpaTransactionManager
,TransactionManager
JpaTransactionManager
for JPA compatible database.-
Nested Class Summary
Nested classes/interfaces inherited from interface google.registry.persistence.transaction.TransactionManager
TransactionManager.ThrowingRunnable
-
Constructor Summary
ConstructorDescriptionJpaTransactionManagerImpl
(jakarta.persistence.EntityManagerFactory emf, Clock clock) JpaTransactionManagerImpl
(jakarta.persistence.EntityManagerFactory emf, Clock clock, boolean readOnly) -
Method Summary
Modifier and TypeMethodDescriptionlong
Returns ainvalid reference
long
id
by a JPA model entity.<T> void
assertDelete
(VKey<T> key) Deletes the entity by its id, throws exception if the entity is not deleted.void
ThrowsIllegalStateException
if the caller is not in a transaction.<T> QueryComposer
<T> createQueryComposer
(Class<T> entity) Returns a QueryComposer which can be used to perform queries against the current database.<T> jakarta.persistence.TypedQuery
<T> criteriaQuery
(jakarta.persistence.criteria.CriteriaQuery<T> criteriaQuery) Creates a JPA SQL query for the given criteria query.void
Deletes the entity by its id.void
Deletes the set of entities by their key id.<T> T
delete
(T entity) Deletes the given entity from the database.<T> boolean
Returns whether the entity of given key exists.boolean
Returns whether the given entity with same ID exists.Return thePersistenceModule.TransactionIsolationLevel
used in the current transaction.Return the defaultPersistenceModule.TransactionIsolationLevel
specified via the config file.jakarta.persistence.EntityManager
Returns theEntityManager
for the current request.jakarta.persistence.metamodel.Metamodel
Returns the JPAMetamodel
.jakarta.persistence.EntityManager
Returns a long-livedEntityManager
not bound to a particular transaction.org.joda.time.DateTime
Returns the time associated with the start of this particular transaction attempt.void
Persists a new entity in the database, throws exception if the entity already exists.void
insertAll
(com.google.common.collect.ImmutableCollection<?> entities) Persists all new entities in the database, throws exception if any entity already exists.void
insertAll
(ImmutableObject... entities) Persists all new entities in the database, throws exception if any entity already exists.boolean
Returnstrue
if the caller is in a transaction.<T> com.google.common.collect.ImmutableList
<T> Returns a list of all entities of the given type that exist in the database.<T> Stream
<T> loadAllOfStream
(Class<T> clazz) Returns a stream of all entities of the given type that exist in the database.<T> com.google.common.collect.ImmutableList
<T> loadByEntities
(Iterable<T> entities) Loads all given entities from the database.<T> com.google.common.collect.ImmutableList
<T> loadByEntitiesIfPresent
(Iterable<T> entities) Loads all given entities from the database if possible.<T> T
loadByEntity
(T entity) Loads the given entity from the database.<T> T
Loads the entity by its key.<T> Optional
<T> loadByKeyIfPresent
(VKey<T> key) Loads the entity by its key, returns empty if the entity doesn't exist.<T> com.google.common.collect.ImmutableMap
<VKey<? extends T>, T> loadByKeys
(Iterable<? extends VKey<? extends T>> keys) Loads the set of entities by their keys.<T> com.google.common.collect.ImmutableMap
<VKey<? extends T>, T> loadByKeysIfPresent
(Iterable<? extends VKey<? extends T>> keys) Loads the set of entities by their keys.<T> Optional
<T> loadSingleton
(Class<T> clazz) Loads the only instance of this particular class, or empty if none exists.void
Persists a new entity or update the existing entity in the database.void
putAll
(com.google.common.collect.ImmutableCollection<?> entities) Persists all new entities or updates the existing entities in the database.void
putAll
(ImmutableObject... entities) Persists all new entities or updates the existing entities in the database.jakarta.persistence.Query
Creates a JPA SQL query for the given query string.<T> jakarta.persistence.TypedQuery
<T> Creates a JPA SQL query for the given query string and result class.void
Executes the work in a (potentially wrapped) transaction and returns the result.<T> T
reTransact
(Callable<T> work) Executes the work in a (potentially wrapped) transaction and returns the result.void
teardown()
Releases all resources and shuts down.void
transact
(PersistenceModule.TransactionIsolationLevel isolationLevel, TransactionManager.ThrowingRunnable work) Executes the work in a transaction at the givenPersistenceModule.TransactionIsolationLevel
.<T> T
transact
(PersistenceModule.TransactionIsolationLevel isolationLevel, Callable<T> work) Executes the work in a transaction at the givenPersistenceModule.TransactionIsolationLevel
and returns the result.void
Executes the work in a transaction.<T> T
Executes the work in a transaction and returns the result.<T> T
transactNoRetry
(PersistenceModule.TransactionIsolationLevel isolationLevel, Callable<T> work) Executes the work in a transaction at the givenPersistenceModule.TransactionIsolationLevel
and returns the result, without retrying upon retryable exceptions.<T> T
transactNoRetry
(Callable<T> work) Executes the work in a transaction and returns the result, without retrying upon retryable exceptions.void
Updates an entity in the database, throws exception if the entity does not exist.void
updateAll
(com.google.common.collect.ImmutableCollection<?> entities) Updates all entities in the database, throws exception if any entity does not exist.void
updateAll
(ImmutableObject... entities) Updates all entities in the database, throws exception if any entity does not exist.
-
Constructor Details
-
JpaTransactionManagerImpl
public JpaTransactionManagerImpl(jakarta.persistence.EntityManagerFactory emf, Clock clock, boolean readOnly) -
JpaTransactionManagerImpl
-
-
Method Details
-
teardown
public void teardown()Description copied from interface:JpaTransactionManager
Releases all resources and shuts down.The errorprone check forbids injection of
Closeable
resources.- Specified by:
teardown
in interfaceJpaTransactionManager
-
getStandaloneEntityManager
public jakarta.persistence.EntityManager getStandaloneEntityManager()Description copied from interface:JpaTransactionManager
Returns a long-livedEntityManager
not bound to a particular transaction.Caller is responsible for closing the returned instance.
- Specified by:
getStandaloneEntityManager
in interfaceJpaTransactionManager
-
getMetaModel
public jakarta.persistence.metamodel.Metamodel getMetaModel()Description copied from interface:JpaTransactionManager
Returns the JPAMetamodel
.- Specified by:
getMetaModel
in interfaceJpaTransactionManager
-
getEntityManager
public jakarta.persistence.EntityManager getEntityManager()Description copied from interface:JpaTransactionManager
Returns theEntityManager
for the current request.The returned instance is closed when the current transaction completes.
Note that in the current implementation the entity manager is obtained from a static
ThreadLocal
object that is set up by the outermostTransactionManager.transact(java.util.concurrent.Callable<T>)
call. Nested call sites have no control over which database instance to use.- Specified by:
getEntityManager
in interfaceJpaTransactionManager
-
query
Description copied from interface:JpaTransactionManager
Creates a JPA SQL query for the given query string and result class.This is a convenience method for the longer
jpaTm().getEntityManager().createQuery(...)
.- Specified by:
query
in interfaceJpaTransactionManager
-
criteriaQuery
public <T> jakarta.persistence.TypedQuery<T> criteriaQuery(jakarta.persistence.criteria.CriteriaQuery<T> criteriaQuery) Description copied from interface:JpaTransactionManager
Creates a JPA SQL query for the given criteria query.- Specified by:
criteriaQuery
in interfaceJpaTransactionManager
-
query
Description copied from interface:JpaTransactionManager
Creates a JPA SQL query for the given query string.This is a convenience method for the longer
jpaTm().getEntityManager().createQuery(...)
.Note that while this method can legally be used for queries that return results, it should not be, as it does not correctly detach entities as must be done for nomulus model objects.
- Specified by:
query
in interfaceJpaTransactionManager
-
inTransaction
public boolean inTransaction()Description copied from interface:TransactionManager
Returnstrue
if the caller is in a transaction.Note that in the current implementation the entity manager is obtained from a static
ThreadLocal
object that is set up by the outermostTransactionManager.transact(java.util.concurrent.Callable<T>)
call. Nested call sites have no control over which database instance to use.- Specified by:
inTransaction
in interfaceTransactionManager
-
allocateId
public long allocateId()Description copied from interface:TransactionManager
Returns ainvalid reference
long
id
by a JPA model entity.The returned value must be project-wide unique when transacting on the primary database instance, but only needs to be unique within a JVM instance when transacting on the replica instance.
- Specified by:
allocateId
in interfaceTransactionManager
-
assertInTransaction
public void assertInTransaction()Description copied from interface:TransactionManager
ThrowsIllegalStateException
if the caller is not in a transaction.Note that this function is kept for backward compatibility. We will review the use case later when adding the cloud sql implementation.
- Specified by:
assertInTransaction
in interfaceTransactionManager
-
reTransact
Description copied from interface:TransactionManager
Executes the work in a (potentially wrapped) transaction and returns the result.Calls to this method are typically going to be in inner functions, that are called either as top-level transactions themselves or are nested inside larger transactions (e.g. a transactional flow). Invocations of reTransact must be vetted to occur in both situations and with such complexity that it is not trivial to refactor out the nested transaction calls. New code should be written in such a way as to avoid requiring reTransact in the first place.
In the future we will be enforcing that
TransactionManager.transact(Callable)
calls be top-level only, with reTransact calls being the only ones that can potentially be an inner nested transaction (which is a noop). Note that, as this can be a nested inner exception, there is no overload provided to specify a (potentially conflicting) transaction isolation level.- Specified by:
reTransact
in interfaceTransactionManager
-
transact
Description copied from interface:TransactionManager
Executes the work in a transaction at the givenPersistenceModule.TransactionIsolationLevel
and returns the result.- Specified by:
transact
in interfaceTransactionManager
-
transact
Description copied from interface:TransactionManager
Executes the work in a transaction and returns the result.- Specified by:
transact
in interfaceTransactionManager
-
transactNoRetry
Description copied from interface:TransactionManager
Executes the work in a transaction and returns the result, without retrying upon retryable exceptions.This method should only be used when the transaction contains side effects that are not rolled back by the transaction manager, for example in
RegistryJpaIO
where the results from a query are streamed to the next transformation inside a transaction, as the result stream has to materialize to a list outside a transaction and doing so would greatly affect the parallelism of the pipeline.- Specified by:
transactNoRetry
in interfaceTransactionManager
-
transactNoRetry
public <T> T transactNoRetry(@Nullable PersistenceModule.TransactionIsolationLevel isolationLevel, Callable<T> work) Description copied from interface:TransactionManager
Executes the work in a transaction at the givenPersistenceModule.TransactionIsolationLevel
and returns the result, without retrying upon retryable exceptions.This method should only be used when the transaction contains side effects that are not rolled back by the transaction manager, for example in
RegistryJpaIO
where the results from a query are streamed to the next transformation inside a transaction, as the result stream has to materialize to a list outside a transaction and doing so would greatly affect the parallelism of the pipeline.- Specified by:
transactNoRetry
in interfaceTransactionManager
-
transact
public void transact(PersistenceModule.TransactionIsolationLevel isolationLevel, TransactionManager.ThrowingRunnable work) Description copied from interface:TransactionManager
Executes the work in a transaction at the givenPersistenceModule.TransactionIsolationLevel
.- Specified by:
transact
in interfaceTransactionManager
-
transact
Description copied from interface:TransactionManager
Executes the work in a transaction.- Specified by:
transact
in interfaceTransactionManager
-
reTransact
Description copied from interface:TransactionManager
Executes the work in a (potentially wrapped) transaction and returns the result.Calls to this method are typically going to be in inner functions, that are called either as top-level transactions themselves or are nested inside larger transactions (e.g. a transactional flow). Invocations of reTransact must be vetted to occur in both situations and with such complexity that it is not trivial to refactor out the nested transaction calls. New code should be written in such a way as to avoid requiring reTransact in the first place.
In the future we will be enforcing that
TransactionManager.transact(ThrowingRunnable)
calls be top-level only, with reTransact calls being the only ones that can potentially be an inner nested transaction (which is a noop). Note that, as this can be a nested inner exception, there is no overload provided to specify a (potentially conflicting) transaction isolation level.- Specified by:
reTransact
in interfaceTransactionManager
-
getDefaultTransactionIsolationLevel
Description copied from interface:JpaTransactionManager
Return the defaultPersistenceModule.TransactionIsolationLevel
specified via the config file.- Specified by:
getDefaultTransactionIsolationLevel
in interfaceJpaTransactionManager
-
getCurrentTransactionIsolationLevel
Description copied from interface:JpaTransactionManager
Return thePersistenceModule.TransactionIsolationLevel
used in the current transaction.- Specified by:
getCurrentTransactionIsolationLevel
in interfaceJpaTransactionManager
-
getTransactionTime
public org.joda.time.DateTime getTransactionTime()Description copied from interface:TransactionManager
Returns the time associated with the start of this particular transaction attempt.- Specified by:
getTransactionTime
in interfaceTransactionManager
-
insert
Description copied from interface:TransactionManager
Persists a new entity in the database, throws exception if the entity already exists.- Specified by:
insert
in interfaceTransactionManager
-
insertAll
public void insertAll(com.google.common.collect.ImmutableCollection<?> entities) Description copied from interface:TransactionManager
Persists all new entities in the database, throws exception if any entity already exists.- Specified by:
insertAll
in interfaceTransactionManager
-
insertAll
Description copied from interface:TransactionManager
Persists all new entities in the database, throws exception if any entity already exists.- Specified by:
insertAll
in interfaceTransactionManager
-
put
Description copied from interface:TransactionManager
Persists a new entity or update the existing entity in the database.- Specified by:
put
in interfaceTransactionManager
-
putAll
Description copied from interface:TransactionManager
Persists all new entities or updates the existing entities in the database.- Specified by:
putAll
in interfaceTransactionManager
-
putAll
public void putAll(com.google.common.collect.ImmutableCollection<?> entities) Description copied from interface:TransactionManager
Persists all new entities or updates the existing entities in the database.- Specified by:
putAll
in interfaceTransactionManager
-
update
Description copied from interface:TransactionManager
Updates an entity in the database, throws exception if the entity does not exist.- Specified by:
update
in interfaceTransactionManager
-
updateAll
public void updateAll(com.google.common.collect.ImmutableCollection<?> entities) Description copied from interface:TransactionManager
Updates all entities in the database, throws exception if any entity does not exist.- Specified by:
updateAll
in interfaceTransactionManager
-
updateAll
Description copied from interface:TransactionManager
Updates all entities in the database, throws exception if any entity does not exist.- Specified by:
updateAll
in interfaceTransactionManager
-
exists
Description copied from interface:TransactionManager
Returns whether the entity of given key exists.- Specified by:
exists
in interfaceTransactionManager
-
exists
Description copied from interface:TransactionManager
Returns whether the given entity with same ID exists.- Specified by:
exists
in interfaceTransactionManager
-
loadByKeyIfPresent
Description copied from interface:TransactionManager
Loads the entity by its key, returns empty if the entity doesn't exist.- Specified by:
loadByKeyIfPresent
in interfaceTransactionManager
-
loadByKeysIfPresent
public <T> com.google.common.collect.ImmutableMap<VKey<? extends T>,T> loadByKeysIfPresent(Iterable<? extends VKey<? extends T>> keys) Description copied from interface:TransactionManager
Loads the set of entities by their keys.Nonexistent keys / entities are absent from the resulting map, but no
NoSuchElementException
will be thrown.- Specified by:
loadByKeysIfPresent
in interfaceTransactionManager
-
loadByEntitiesIfPresent
Description copied from interface:TransactionManager
Loads all given entities from the database if possible.Nonexistent entities are absent from the resulting list, but no
NoSuchElementException
will be thrown.- Specified by:
loadByEntitiesIfPresent
in interfaceTransactionManager
-
loadByKey
Description copied from interface:TransactionManager
Loads the entity by its key.- Specified by:
loadByKey
in interfaceTransactionManager
-
loadByKeys
public <T> com.google.common.collect.ImmutableMap<VKey<? extends T>,T> loadByKeys(Iterable<? extends VKey<? extends T>> keys) Description copied from interface:TransactionManager
Loads the set of entities by their keys.- Specified by:
loadByKeys
in interfaceTransactionManager
-
loadByEntity
public <T> T loadByEntity(T entity) Description copied from interface:TransactionManager
Loads the given entity from the database.- Specified by:
loadByEntity
in interfaceTransactionManager
-
loadByEntities
Description copied from interface:TransactionManager
Loads all given entities from the database.- Specified by:
loadByEntities
in interfaceTransactionManager
-
loadAllOf
Description copied from interface:TransactionManager
Returns a list of all entities of the given type that exist in the database.The resulting list is empty if there are no entities of this type.
- Specified by:
loadAllOf
in interfaceTransactionManager
-
loadAllOfStream
Description copied from interface:TransactionManager
Returns a stream of all entities of the given type that exist in the database.The resulting stream is empty if there are no entities of this type.
- Specified by:
loadAllOfStream
in interfaceTransactionManager
-
loadSingleton
Description copied from interface:TransactionManager
Loads the only instance of this particular class, or empty if none exists.Throws an exception if there is more than one element in the table.
- Specified by:
loadSingleton
in interfaceTransactionManager
-
delete
Description copied from interface:TransactionManager
Deletes the entity by its id.- Specified by:
delete
in interfaceTransactionManager
-
delete
Description copied from interface:TransactionManager
Deletes the set of entities by their key id.- Specified by:
delete
in interfaceTransactionManager
-
delete
public <T> T delete(T entity) Description copied from interface:TransactionManager
Deletes the given entity from the database.This returns the deleted entity, which may not necessarily be the same as the original entity passed in, as it may be a) converted to a different type of object more appropriate to the database type or b) merged with an object managed by the database entity manager.
- Specified by:
delete
in interfaceTransactionManager
-
createQueryComposer
Description copied from interface:TransactionManager
Returns a QueryComposer which can be used to perform queries against the current database.- Specified by:
createQueryComposer
in interfaceTransactionManager
-
assertDelete
Description copied from interface:JpaTransactionManager
Deletes the entity by its id, throws exception if the entity is not deleted.- Specified by:
assertDelete
in interfaceJpaTransactionManager
-