diff options
author | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2025-07-03 20:02:00 +0200 |
---|---|---|
committer | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2025-07-04 05:10:18 +0200 |
commit | 9cff6e2f790b7f585c7f3a8dc5398b8dbe2d8554 (patch) | |
tree | d8655602fdb709339422b6d7a84ebf27815b6c45 | |
parent | 5885dad9b66a100423e4b1f856bd10ae00792258 (diff) |
Revert "Use Blaze Persistence for criteria queries."
This reverts commit ab36adbbc22fcd156ddce528a9ff5e5103623342.
Change-Id: I335ec7d02bd0d53655ca4b07bed9ee4a0c01ce04
-rw-r--r-- | pom.xml | 24 | ||||
-rw-r--r-- | src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java | 117 | ||||
-rw-r--r-- | src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java | 29 |
3 files changed, 66 insertions, 104 deletions
@@ -29,7 +29,6 @@ <spotless-plugin.version>2.43.0</spotless-plugin.version> <basic-annotations.version>0.2.0</basic-annotations.version> - <blaze-persistence.version>1.6.12</blaze-persistence.version> <findbugs-jsr305.version>3.0.2</findbugs-jsr305.version> <flexmark.version>0.64.8</flexmark.version> <google.java.format.version>1.15.0</google.java.format.version> @@ -55,14 +54,6 @@ <scope>import</scope> </dependency> - <dependency> - <groupId>com.blazebit</groupId> - <artifactId>blaze-persistence-bom</artifactId> - <version>${blaze-persistence.version}</version> - <type>pom</type> - <scope>import</scope> - </dependency> - <!-- Hibernate PostgreSQL Extra Types --> <dependency> <groupId>io.hypersistence</groupId> @@ -202,22 +193,9 @@ <artifactId>quarkus-container-image-jib</artifactId> </dependency> + <!-- Quarkus universe --> <dependency> - <groupId>com.blazebit</groupId> - <artifactId>blaze-persistence-integration-quarkus-3</artifactId> - </dependency> - <dependency> - <groupId>com.blazebit</groupId> - <artifactId>blaze-persistence-integration-hibernate-6.2</artifactId> - <scope>runtime</scope> - </dependency> - <dependency> - <groupId>com.blazebit</groupId> - <artifactId>blaze-persistence-entity-view-processor</artifactId> - <scope>provided</scope> - </dependency> - <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-mail</artifactId> </dependency> diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java index e757972..eeee6cf 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java @@ -2,22 +2,18 @@ package eu.mulk.mulkcms2.benki.posts; import static java.util.stream.Collectors.toList; -import com.blazebit.persistence.CriteriaBuilder; -import com.blazebit.persistence.CriteriaBuilderFactory; import eu.mulk.mulkcms2.benki.accesscontrol.Role; import eu.mulk.mulkcms2.benki.bookmarks.Bookmark; import eu.mulk.mulkcms2.benki.lazychat.LazychatMessage; import eu.mulk.mulkcms2.benki.newsletter.Newsletter; import eu.mulk.mulkcms2.benki.users.User; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; +import eu.mulk.mulkcms2.benki.users.User_; import io.quarkus.hibernate.orm.panache.PanacheEntityBase; import jakarta.annotation.Nullable; import jakarta.json.bind.annotation.JsonbTransient; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EntityManager; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; @@ -35,6 +31,11 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.OrderBy; import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.From; +import jakarta.persistence.criteria.JoinType; +import jakarta.persistence.criteria.Predicate; import java.time.LocalDate; import java.time.OffsetDateTime; import java.util.ArrayList; @@ -48,9 +49,12 @@ import java.util.Set; import java.util.TimeZone; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.CheckForNull; -import org.hibernate.annotations.Type; +import org.hibernate.Session; +import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.annotations.SQLRestriction; +import org.hibernate.type.SqlTypes; @Entity @Table(name = "posts", schema = "benki") @@ -171,76 +175,80 @@ public abstract class Post<Text extends PostText<?>> extends PanacheEntityBase { } } - protected static <T extends Post<?>> CriteriaBuilder<T> queryViewable( + protected static <T extends Post> CriteriaQuery<T> queryViewable( Class<T> entityClass, @CheckForNull User reader, @CheckForNull User owner, @CheckForNull Integer cursor, - EntityManager em, - CriteriaBuilderFactory cbf, + CriteriaBuilder cb, boolean forward, @CheckForNull String searchQuery) { + CriteriaQuery<T> query = cb.createQuery(entityClass); - CriteriaBuilder<T> cb = cbf.create(em, entityClass).select("post"); + var conditions = new ArrayList<Predicate>(); + From<?, T> post; if (reader == null) { - cb = - cb.from(entityClass, "post") - .innerJoin("post.targets", "role") - .where("'world'") - .isMemberOf("role.tags"); + post = query.from(entityClass); + var target = post.join(Post_.targets); + conditions.add(cb.equal(target, Role.getWorld())); } else { - cb = cb.from(User.class, "user").where("user").eq(reader); + var root = query.from(User.class); + conditions.add(cb.equal(root, reader)); if (entityClass.isAssignableFrom(Post.class)) { - cb = cb.innerJoin("user.visiblePosts", "post"); + post = (From<?, T>) root.join(User_.visiblePosts); } else if (entityClass.isAssignableFrom(Bookmark.class)) { - cb = cb.innerJoin("user.visibleBookmarks", "post"); + post = (From<?, T>) root.join(User_.visibleBookmarks); } else if (entityClass.isAssignableFrom(LazychatMessage.class)) { - cb = cb.innerJoin("user.visibleLazychatMessages", "post"); + post = (From<?, T>) root.join(User_.visibleLazychatMessages); } else { throw new IllegalArgumentException(); } } - cb = cb.fetch("post.owner"); + query.select(post); + post.fetch(Post_.owner, JoinType.LEFT); if (owner != null) { - cb = cb.where("post.owner").eq(owner); + conditions.add(cb.equal(post.get(Post_.owner), owner)); } if (forward) { - cb = cb.orderByDesc("post.id"); + query.orderBy(cb.desc(post.get(Post_.id))); } else { - cb = cb.orderByAsc("post.id"); + query.orderBy(cb.asc(post.get(Post_.id))); } if (cursor != null) { if (forward) { - cb = cb.where("post.id").le(cursor); + conditions.add(cb.le(post.get(Post_.id), cursor)); } else { - cb = cb.where("post.id").gt(cursor); + conditions.add(cb.gt(post.get(Post_.id), cursor)); } } if (searchQuery != null && !searchQuery.isBlank()) { - cb = - cb.whereExists() - .from(PostText.class, "postText") - .where("postText.post") - .eqExpression("post") - .whereOr() - .whereExpression( - "post_matches_websearch(postText.searchTerms, 'de', :searchQueryText) = true") - .whereExpression( - "post_matches_websearch(postText.searchTerms, 'en', :searchQueryText) = true") - .endOr() - .end() - .setParameter("searchQueryText", searchQuery); + var postTexts = post.join(Post_.texts); + var localizedSearches = + Stream.of("de", "en") + .map( + language -> + cb.isTrue( + cb.function( + "post_matches_websearch", + Boolean.class, + postTexts.get(PostText_.searchTerms), + cb.literal(language), + cb.literal(searchQuery)))) + .toArray(n -> new Predicate[n]); + conditions.add(cb.or(localizedSearches)); } - cb = cb.where("post.scope").eq(Scope.top_level); + conditions.add(cb.equal(post.get(Post_.scope), Scope.top_level)); - return cb; + query.where(conditions.toArray(new Predicate[0])); + + return query; } public final boolean isVisibleTo(@Nullable User user) { @@ -312,18 +320,13 @@ public abstract class Post<Text extends PostText<?>> extends PanacheEntityBase { } public static PostPage<Post<? extends PostText<?>>> findViewable( - PostFilter postFilter, - EntityManager em, - CriteriaBuilderFactory cbf, - @CheckForNull User viewer, - @CheckForNull User owner) { - return findViewable(postFilter, em, cbf, viewer, owner, null, null, null); + PostFilter postFilter, Session session, @CheckForNull User viewer, @CheckForNull User owner) { + return findViewable(postFilter, session, viewer, owner, null, null, null); } public static PostPage<Post<? extends PostText<?>>> findViewable( PostFilter postFilter, - EntityManager em, - CriteriaBuilderFactory cbf, + Session session, @CheckForNull User viewer, @CheckForNull User owner, @CheckForNull Integer cursor, @@ -340,13 +343,12 @@ public abstract class Post<Text extends PostText<?>> extends PanacheEntityBase { default: entityClass = Post.class; } - return findViewable(entityClass, em, cbf, viewer, owner, cursor, count, searchQuery); + return findViewable(entityClass, session, viewer, owner, cursor, count, searchQuery); } protected static <T extends Post<? extends PostText<?>>> PostPage<T> findViewable( Class<? extends T> entityClass, - EntityManager em, - CriteriaBuilderFactory cbf, + Session session, @CheckForNull User viewer, @CheckForNull User owner, @CheckForNull Integer cursor, @@ -357,9 +359,10 @@ public abstract class Post<Text extends PostText<?>> extends PanacheEntityBase { Objects.requireNonNull(count); } - var forwardCriteria = - queryViewable(entityClass, viewer, owner, cursor, em, cbf, true, searchQuery); - var forwardQuery = forwardCriteria.getQuery(); + var cb = session.getCriteriaBuilder(); + + var forwardCriteria = queryViewable(entityClass, viewer, owner, cursor, cb, true, searchQuery); + var forwardQuery = session.createQuery(forwardCriteria); if (count != null) { forwardQuery.setMaxResults(count + 1); @@ -371,8 +374,8 @@ public abstract class Post<Text extends PostText<?>> extends PanacheEntityBase { if (cursor != null) { // Look backwards as well so we can find the prevCursor. var backwardCriteria = - queryViewable(entityClass, viewer, owner, cursor, em, cbf, false, searchQuery); - var backwardQuery = backwardCriteria.getQuery(); + queryViewable(entityClass, viewer, owner, cursor, cb, false, searchQuery); + var backwardQuery = session.createQuery(backwardCriteria); backwardQuery.setMaxResults(count); var backwardResults = backwardQuery.getResultList(); if (!backwardResults.isEmpty()) { @@ -380,7 +383,7 @@ public abstract class Post<Text extends PostText<?>> extends PanacheEntityBase { } } - var forwardResults = new ArrayList<T>(forwardQuery.getResultList()); + var forwardResults = (List<T>) forwardQuery.getResultList(); if (count != null) { if (forwardResults.size() == count + 1) { nextCursor = forwardResults.get(count).id; diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java index c8090ba..58b29a6 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java @@ -6,7 +6,6 @@ import static jakarta.ws.rs.core.MediaType.TEXT_HTML; import static jakarta.ws.rs.core.MediaType.TEXT_PLAIN; import static java.nio.charset.StandardCharsets.UTF_8; -import com.blazebit.persistence.CriteriaBuilderFactory; import com.rometools.rome.feed.atom.Content; import com.rometools.rome.feed.atom.Entry; import com.rometools.rome.feed.atom.Feed; @@ -121,8 +120,6 @@ public abstract class PostResource { @PersistenceContext protected EntityManager entityManager; - @Inject protected CriteriaBuilderFactory criteriaBuilderFactory; - private final SecureRandom secureRandom; private final PostFilter postFilter; @@ -145,16 +142,8 @@ public abstract class PostResource { maxResults = maxResults == null ? defaultMaxResults : maxResults; @CheckForNull var reader = getCurrentUser(); - var q = - Post.findViewable( - postFilter, - entityManager, - criteriaBuilderFactory, - reader, - null, - cursor, - maxResults, - searchQuery); + var session = entityManager.unwrap(Session.class); + var q = Post.findViewable(postFilter, session, reader, null, cursor, maxResults, searchQuery); q.cacheDescriptions(); @@ -192,16 +181,8 @@ public abstract class PostResource { @CheckForNull var reader = getCurrentUser(); var owner = User.findByNickname(ownerName); - var q = - Post.findViewable( - postFilter, - entityManager, - criteriaBuilderFactory, - reader, - owner, - cursor, - maxResults, - null); + var session = entityManager.unwrap(Session.class); + var q = Post.findViewable(postFilter, session, reader, owner, cursor, maxResults, null); q.cacheDescriptions(); @@ -373,7 +354,7 @@ public abstract class PostResource { private String makeFeed( @CheckForNull User reader, @Nullable User owner, @Nullable String ownerName) throws FeedException { - var q = Post.findViewable(postFilter, entityManager, criteriaBuilderFactory, reader, owner); + var q = Post.findViewable(postFilter, entityManager.unwrap(Session.class), reader, owner); q.cacheDescriptions(); var posts = q.posts; |