I am developing a repository as a service application. An application that let users create their endpoints with queries via a web interface. This application uses either Hibernate or Eclipselink as a JPA provider. The challenge is to check if the supplied user string (query) is a native SQL or a JPQL and that Eclipselink and Hibernate handles this differently, so I decided to wrap it behind this simple checker.
QueryTypeChecker.java
package com.johnpili.query_type_checker;
import jakarta.persistence.Query;
import org.eclipse.persistence.internal.jpa.EJBQueryImpl;
import org.hibernate.query.sql.internal.NativeQueryImpl;
import org.hibernate.query.sqm.internal.QuerySqmImpl;
public interface QueryTypeChecker {
enum QueryType {
JPQL,
SQL
}
default QueryType getQueryType(Query query) throws Exception {
if (query instanceof EJBQueryImpl ejbQuery) {
if(ejbQuery.getDatabaseQuery().isJPQLCallQuery()) {
return QueryType.JPQL;
}
if(ejbQuery.getDatabaseQuery().isSQLCallQuery()) {
return QueryType.SQL;
}
}
if(query instanceof QuerySqmImpl<?>) {
return QueryType.JPQL;
}
if(query instanceof NativeQueryImpl) {
return QueryType.SQL;
}
throw new Exception("Unknown type");
}
}
package com.johnpili.query_type_checker.hibernate;
import com.johnpili.query_type_checker.QueryTypeChecker;
import com.johnpili.query_type_checker.QueryTypeCheckerImpl;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import jakarta.persistence.Query;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class TestApplication {
QueryTypeChecker queryTypeChecker = new QueryTypeCheckerImpl();
@Test
public void testIsSQLQuery() {
try (EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("my-persistence-unit")) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createNativeQuery("SELECT * FROM material");
Assertions.assertEquals(QueryTypeChecker.QueryType.SQL, queryTypeChecker.getQueryType(query));
} catch (Exception exception) {
Assertions.fail(exception);
}
}
@Test
public void testIsJPQLQuery() {
try (EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("my-persistence-unit")) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createQuery("SELECT o FROM ProductionOrder o", ProductionOrder.class);
Assertions.assertEquals(QueryTypeChecker.QueryType.JPQL, queryTypeChecker.getQueryType(query));
} catch (Exception exception) {
Assertions.fail(exception);
}
}
}