Use detaching queries for all criteria queries (#1192)

* Make all criteria queries use jpaTm().query()

This causes all criteria queries to detach-on-load.

* Detach results of criteria queries

Wrap the criteria queries in DetachingTypedQuery now that the latter is
merged.
This commit is contained in:
Michael Muller 2021-06-04 14:37:53 -04:00 committed by GitHub
parent d7f7568761
commit 886a970ed6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 50 additions and 25 deletions

View file

@ -228,8 +228,7 @@ public abstract class ForeignKeyIndex<E extends EppResource> extends BackupGroup
tm().transact(
() ->
jpaTm()
.getEntityManager()
.createQuery(
.query(
CriteriaQueryBuilder.create(clazz)
.whereFieldIsIn(property, foreignKeys)
.build())

View file

@ -164,8 +164,7 @@ public class HistoryEntryDao {
private static <T extends HistoryEntry> Stream<T> loadHistoryObjectFromSqlByRegistrars(
Class<T> historyClass, ImmutableCollection<String> registrarIds) {
return jpaTm()
.getEntityManager()
.createQuery(
.query(
CriteriaQueryBuilder.create(historyClass)
.whereFieldIsIn("clientId", registrarIds)
.build())
@ -189,7 +188,7 @@ public class HistoryEntryDao {
return ImmutableList.sortedCopyOf(
Comparator.comparing(HistoryEntry::getModificationTime),
jpaTm().getEntityManager().createQuery(criteriaQuery).getResultList());
jpaTm().query(criteriaQuery).getResultList());
}
private static Class<? extends HistoryEntry> getHistoryClassFromParent(
@ -216,8 +215,7 @@ public class HistoryEntryDao {
Class<T> historyClass, DateTime afterTime, DateTime beforeTime) {
CriteriaBuilder criteriaBuilder = jpaTm().getEntityManager().getCriteriaBuilder();
return jpaTm()
.getEntityManager()
.createQuery(
.query(
CriteriaQueryBuilder.create(historyClass)
.where("modificationTime", criteriaBuilder::greaterThanOrEqualTo, afterTime)
.where("modificationTime", criteriaBuilder::lessThanOrEqualTo, beforeTime)

View file

@ -19,6 +19,7 @@ import java.util.function.Supplier;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaQuery;
/** Sub-interface of {@link TransactionManager} which defines JPA related methods. */
public interface JpaTransactionManager extends TransactionManager {
@ -34,6 +35,9 @@ public interface JpaTransactionManager extends TransactionManager {
*/
<T> TypedQuery<T> query(String sqlString, Class<T> resultClass);
/** Creates a JPA SQU query for the given criteria query. */
<T> TypedQuery<T> query(CriteriaQuery<T> criteriaQuery);
/**
* Creates a JPA SQL query for the given query string.
*

View file

@ -69,6 +69,7 @@ import javax.persistence.PersistenceException;
import javax.persistence.Query;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.SingularAttribute;
import org.joda.time.DateTime;
@ -127,6 +128,11 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
return new DetachingTypedQuery(getEntityManager().createQuery(sqlString, resultClass));
}
@Override
public <T> TypedQuery<T> query(CriteriaQuery<T> criteriaQuery) {
return new DetachingTypedQuery(getEntityManager().createQuery(criteriaQuery));
}
@Override
public Query query(String sqlString) {
return getEntityManager().createQuery(sqlString);

View file

@ -589,8 +589,7 @@ public class RdapDomainSearchAction extends RdapSearchActionBase {
cursorString.get());
}
jpaTm()
.getEntityManager()
.createQuery(queryBuilder.build())
.query(queryBuilder.build())
.getResultStream()
.filter(this::isAuthorized)
.forEach(

View file

@ -202,11 +202,7 @@ public abstract class RdapSearchActionBase extends RdapActionBase {
desiredRegistrar.get());
}
List<T> queryResult =
jpaTm()
.getEntityManager()
.createQuery(builder.build())
.setMaxResults(querySizeLimit)
.getResultList();
jpaTm().query(builder.build()).setMaxResults(querySizeLimit).getResultList();
if (checkForVisibility) {
return filterResourcesByVisibility(queryResult, querySizeLimit);
} else {

View file

@ -59,8 +59,7 @@ class CriteriaQueryBuilderTest {
.transact(
() ->
jpaTm()
.getEntityManager()
.createQuery(
.query(
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
.build())
.getResultList()))
@ -77,10 +76,11 @@ class CriteriaQueryBuilderTest {
CriteriaQuery<CriteriaQueryBuilderTestEntity> query =
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
.where(
"data", jpaTm().getEntityManager().getCriteriaBuilder()::equal,
"data",
jpaTm().getEntityManager().getCriteriaBuilder()::equal,
"zztz")
.build();
return jpaTm().getEntityManager().createQuery(query).getResultList();
return jpaTm().query(query).getResultList();
});
assertThat(result).containsExactly(entity2);
}
@ -96,7 +96,7 @@ class CriteriaQueryBuilderTest {
.where(
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "a%")
.build();
return jpaTm().getEntityManager().createQuery(query).getResultList();
return jpaTm().query(query).getResultList();
});
assertThat(result).containsExactly(entity3);
}
@ -112,7 +112,7 @@ class CriteriaQueryBuilderTest {
.where(
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "%a%")
.build();
return jpaTm().getEntityManager().createQuery(query).getResultList();
return jpaTm().query(query).getResultList();
});
assertThat(result).containsExactly(entity1, entity3).inOrder();
}
@ -132,7 +132,7 @@ class CriteriaQueryBuilderTest {
.where(
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "%t%")
.build();
return jpaTm().getEntityManager().createQuery(query).getResultList();
return jpaTm().query(query).getResultList();
});
assertThat(result).containsExactly(entity1);
}
@ -147,7 +147,7 @@ class CriteriaQueryBuilderTest {
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
.whereFieldIsIn("data", ImmutableList.of("aaa", "bbb"))
.build();
return jpaTm().getEntityManager().createQuery(query).getResultList();
return jpaTm().query(query).getResultList();
});
assertThat(result).containsExactly(entity3).inOrder();
}
@ -162,7 +162,7 @@ class CriteriaQueryBuilderTest {
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
.whereFieldIsIn("data", ImmutableList.of("aaa", "bbb", "data"))
.build();
return jpaTm().getEntityManager().createQuery(query).getResultList();
return jpaTm().query(query).getResultList();
});
assertThat(result).containsExactly(entity1, entity3).inOrder();
}
@ -179,7 +179,7 @@ class CriteriaQueryBuilderTest {
.where(
"data", jpaTm().getEntityManager().getCriteriaBuilder()::like, "%a%")
.build();
return jpaTm().getEntityManager().createQuery(query).getResultList();
return jpaTm().query(query).getResultList();
});
assertThat(result).containsExactly(entity3, entity1).inOrder();
}
@ -194,7 +194,7 @@ class CriteriaQueryBuilderTest {
CriteriaQueryBuilder.create(CriteriaQueryBuilderTestEntity.class)
.orderByDesc("data")
.build();
return jpaTm().getEntityManager().createQuery(query).getResultList();
return jpaTm().query(query).getResultList();
});
assertThat(result).containsExactly(entity2, entity1, entity3).inOrder();
}

View file

@ -585,6 +585,29 @@ class JpaTransactionManagerImplTest {
.contains("Inserted/updated object reloaded: ");
}
@Test
void cqQuery_detaches() {
jpaTm().transact(() -> jpaTm().insertAll(moreEntities));
jpaTm()
.transact(
() ->
assertThat(
jpaTm()
.getEntityManager()
.contains(
jpaTm()
.query(
CriteriaQueryBuilder.create(TestEntity.class)
.where(
"name",
jpaTm().getEntityManager().getCriteriaBuilder()
::equal,
"entity1")
.build())
.getSingleResult()))
.isFalse());
}
@Test
void loadAfterPut_fails() {
assertThat(