Skip to content

Commit

Permalink
Escape column names in generated "oreder by" clause of hybernate query
Browse files Browse the repository at this point in the history
  • Loading branch information
Vitaliy Baschlykoff committed Nov 16, 2023
1 parent 90f0bb3 commit 3c3e7e1
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import jakarta.transaction.TransactionManager;

import org.hibernate.Session;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;

import io.agroal.api.AgroalDataSource;
import io.quarkus.agroal.DataSource;
Expand Down Expand Up @@ -209,7 +211,8 @@ public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Sort sor
}

String translatedHqlQuery = PanacheJpaUtil.createFindQuery(entityClass, panacheQuery, paramCount(params));
return createPanacheQuery(em, translatedHqlQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort), params);
Dialect dialect = em.unwrap(SessionFactoryImplementor.class).getJdbcServices().getDialect();
return createPanacheQuery(em, translatedHqlQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort, dialect), params);
}

public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Map<String, Object> params) {
Expand All @@ -230,7 +233,8 @@ public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Sort sor
}

String translatedHqlQuery = PanacheJpaUtil.createFindQuery(entityClass, panacheQuery, paramCount(params));
return createPanacheQuery(em, translatedHqlQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort), params);
Dialect dialect = em.unwrap(SessionFactoryImplementor.class).getJdbcServices().getDialect();
return createPanacheQuery(em, translatedHqlQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort, dialect), params);
}

public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Parameters params) {
Expand Down Expand Up @@ -298,7 +302,8 @@ public PanacheQueryType findAll(Class<?> entityClass) {
public PanacheQueryType findAll(Class<?> entityClass, Sort sort) {
String query = "FROM " + PanacheJpaUtil.getEntityName(entityClass);
EntityManager em = getEntityManager(entityClass);
return createPanacheQuery(em, query, null, PanacheJpaUtil.toOrderBy(sort), null);
Dialect dialect = em.unwrap(SessionFactoryImplementor.class).getJdbcServices().getDialect();
return createPanacheQuery(em, query, null, PanacheJpaUtil.toOrderBy(sort, dialect), null);
}

public List<?> listAll(Class<?> entityClass) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.hibernate.dialect.*;
import org.junit.jupiter.api.Test;

import io.quarkus.panache.common.Sort;
Expand All @@ -18,7 +19,7 @@ public void testEmptySortByYieldsEmptyString() {
@Test
public void testSortBy() {
Sort sort = Sort.by("foo", "bar");
assertEquals(" ORDER BY foo , bar", PanacheJpaUtil.toOrderBy(sort));
assertEquals(" ORDER BY \"foo\" , \"bar\"", PanacheJpaUtil.toOrderBy(sort, new H2Dialect()));
}

@Test
Expand All @@ -30,13 +31,13 @@ public void testEmptySortEmptyYieldsEmptyString() {
@Test
public void testSortByNullsFirst() {
Sort emptySort = Sort.by("foo", Sort.Direction.Ascending, Sort.NullPrecedence.NULLS_FIRST);
assertEquals(" ORDER BY foo NULLS FIRST", PanacheJpaUtil.toOrderBy(emptySort));
assertEquals(" ORDER BY `foo` NULLS FIRST", PanacheJpaUtil.toOrderBy(emptySort, new MySQLDialect()));
}

@Test
public void testSortByNullsLast() {
Sort emptySort = Sort.by("foo", Sort.Direction.Descending, Sort.NullPrecedence.NULLS_LAST);
assertEquals(" ORDER BY foo DESC NULLS LAST", PanacheJpaUtil.toOrderBy(emptySort));
assertEquals(" ORDER BY [foo] DESC NULLS LAST", PanacheJpaUtil.toOrderBy(emptySort, new SQLServerDialect()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.Metamodel;

import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.CascadingActions;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.metamodel.model.domain.internal.EntityTypeImpl;

Expand All @@ -33,7 +35,8 @@ public static PanacheQuery<?> find(AbstractJpaOperations<?> jpaOperations, Class
String countQuery, Sort sort, Map<String, Object> params) {
String findQuery = createFindQuery(entityClass, query, jpaOperations.paramCount(params));
EntityManager em = jpaOperations.getEntityManager();
Query jpaQuery = em.createQuery(sort != null ? findQuery + toOrderBy(sort) : findQuery);
Dialect dialect = em.unwrap(SessionFactoryImplementor.class).getJdbcServices().getDialect();
Query jpaQuery = em.createQuery(sort != null ? findQuery + toOrderBy(sort, dialect) : findQuery);
JpaOperations.bindParameters(jpaQuery, params);
return new CustomCountPanacheQuery(em, jpaQuery, countQuery, params);
}
Expand All @@ -48,7 +51,8 @@ public static PanacheQuery<?> find(AbstractJpaOperations<?> jpaOperations, Class
String countQuery, Sort sort, Object... params) {
String findQuery = createFindQuery(entityClass, query, jpaOperations.paramCount(params));
EntityManager em = jpaOperations.getEntityManager();
Query jpaQuery = em.createQuery(sort != null ? findQuery + toOrderBy(sort) : findQuery);
Dialect dialect = em.unwrap(SessionFactoryImplementor.class).getJdbcServices().getDialect();
Query jpaQuery = em.createQuery(sort != null ? findQuery + toOrderBy(sort, dialect) : findQuery);
JpaOperations.bindParameters(jpaQuery, params);
return new CustomCountPanacheQuery(em, jpaQuery, countQuery, params);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import jakarta.persistence.LockModeType;

import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.LockModeConverter;
import org.hibernate.reactive.mutiny.Mutiny;
import org.hibernate.reactive.mutiny.Mutiny.Session;
Expand Down Expand Up @@ -109,6 +111,7 @@ public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Object..

public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Sort sort, Object... params) {
Uni<Mutiny.Session> session = getSession();
Dialect dialect = ((SessionFactoryImplementor) SessionOperations.getSessionFactory()).getJdbcServices().getDialect();
if (PanacheJpaUtil.isNamedQuery(panacheQuery)) {
String namedQuery = panacheQuery.substring(1);
if (sort != null) {
Expand All @@ -117,10 +120,10 @@ public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Sort sor
+ "\" instead");
}
NamedQueryUtil.checkNamedQuery(entityClass, namedQuery);
return createPanacheQuery(session, panacheQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort), params);
return createPanacheQuery(session, panacheQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort, dialect), params);
}
String hqlQuery = PanacheJpaUtil.createFindQuery(entityClass, panacheQuery, paramCount(params));
return createPanacheQuery(session, hqlQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort), params);
return createPanacheQuery(session, hqlQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort, dialect), params);
}

public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Map<String, Object> params) {
Expand All @@ -129,6 +132,7 @@ public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Map<Stri

public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Sort sort, Map<String, Object> params) {
Uni<Mutiny.Session> session = getSession();
Dialect dialect = ((SessionFactoryImplementor) SessionOperations.getSessionFactory()).getJdbcServices().getDialect();
if (PanacheJpaUtil.isNamedQuery(panacheQuery)) {
String namedQuery = panacheQuery.substring(1);
if (sort != null) {
Expand All @@ -137,10 +141,10 @@ public PanacheQueryType find(Class<?> entityClass, String panacheQuery, Sort sor
+ "\" instead");
}
NamedQueryUtil.checkNamedQuery(entityClass, namedQuery);
return createPanacheQuery(session, panacheQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort), params);
return createPanacheQuery(session, panacheQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort, dialect), params);
}
String hqlQuery = PanacheJpaUtil.createFindQuery(entityClass, panacheQuery, paramCount(params));
return createPanacheQuery(session, hqlQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort), params);
return createPanacheQuery(session, hqlQuery, panacheQuery, PanacheJpaUtil.toOrderBy(sort, dialect), params);
}

public PanacheQueryType find(Class<?> entityClass, String query, Parameters params) {
Expand Down Expand Up @@ -184,7 +188,8 @@ public PanacheQueryType findAll(Class<?> entityClass) {
public PanacheQueryType findAll(Class<?> entityClass, Sort sort) {
String query = "FROM " + PanacheJpaUtil.getEntityName(entityClass);
Uni<Mutiny.Session> session = getSession();
return createPanacheQuery(session, query, null, PanacheJpaUtil.toOrderBy(sort), null);
Dialect dialect = ((SessionFactoryImplementor) SessionOperations.getSessionFactory()).getJdbcServices().getDialect();
return createPanacheQuery(session, query, null, PanacheJpaUtil.toOrderBy(sort, dialect), null);
}

public Uni<List<?>> listAll(Class<?> entityClass) {
Expand Down
4 changes: 4 additions & 0 deletions extensions/panache/panache-hibernate-common/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;

import io.quarkus.panache.common.Sort;
import io.quarkus.panache.common.exception.PanacheQueryException;

Expand All @@ -17,6 +20,8 @@ public class PanacheJpaUtil {
static final Pattern FROM_PATTERN = Pattern.compile("^\\s*FROM\\s+.*",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

static final Dialect DEFAULT_DIALECT = new H2Dialect();

public static String getCountQuery(String query) {
// try to generate a good count query from the existing query
Matcher selectMatcher = SELECT_PATTERN.matcher(query);
Expand Down Expand Up @@ -163,7 +168,12 @@ public static String createDeleteQuery(Class<?> entityClass, String query, int p
return "DELETE FROM " + getEntityName(entityClass) + " WHERE " + query;
}

@Deprecated
public static String toOrderBy(Sort sort) {
return toOrderBy(sort, DEFAULT_DIALECT);
}

public static String toOrderBy(Sort sort, Dialect dialect) {
if (sort == null) {
return null;
}
Expand All @@ -175,7 +185,7 @@ public static String toOrderBy(Sort sort) {
Sort.Column column = sort.getColumns().get(i);
if (i > 0)
sb.append(" , ");
sb.append(column.getName());
sb.append(dialect == null ? column.getName() : dialect.toQuotedIdentifier(column.getName()));
if (column.getDirection() != Sort.Direction.Ascending) {
sb.append(" DESC");
}
Expand Down

0 comments on commit 3c3e7e1

Please sign in to comment.