JPAExpressions 와 SQLExpressions 를 섞어서 사용할 수 없기 때문에 사용자가 수동으로 함수를 등록해주어야 한다. (대소문자는 상관없다)

이는 QueryDSL 에서도 적용이 되는데, 먼저 DB 설정에서 Adapter 를 설정해줄 때 아래와 같이 코드를 입력해주고, EntityManagerFactory 에서 사용하도록 해준다.

...

@Bean
public JpaVendorAdapter dbJpaVendorAdapter() {
    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
    adapter.setDatabasePlatform("kr.pe.karsei.configs.DbDialect"); // Dialect 연결
    adapter.setDatabase(Database.ORACLE);

    return adapter;
}

@Bean
public EntityManagerFactory dbEntityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setDataSource(dataSource);
    entityManagerFactoryBean.setPersistenceUnitName("oracleEntity");
    entityManagerFactoryBean.setPackagesToScan("kr.pe.karsei.entities");
    entityManagerFactoryBean.setJpaVendorAdapter(dbJpaVendorAdapter()); // Adapter 연결
    entityManagerFactoryBean.afterPropertiesSet();

    return entityManagerFactoryBean.getObject();
}

...

그리고 아래와 같이 Oracle 에 대한 Dialect Class 를 만들어 준다.

public class MainDbDialect extends Oracle10gDialect {
    public MainDbDialect() {
        super();
        // JPAExpressions 와 SQLExpressions 를 섞어서 사용할 수 없기 때문에 수동으로 등록해주어야 한다. (대소문자 상관없음)
        // https://github.com/querydsl/querydsl/issues/2377#issuecomment-457435922
        this.registerFunction("RULE_CATEGORY_PACKAGE.GETCATEGORYPATHSEQNOS", new SQLFunctionTemplate(StandardBasicTypes.STRING, "RULE_CATEGORY_PACKAGE.GETCATEGORYPATHSEQNOS(?1)"));
        this.registerFunction("REGEXP_SUBSTR", new StandardSQLFunction("REGEXP_SUBSTR", StandardBasicTypes.STRING));
        this.registerFunction("TO_NUMBER", new StandardSQLFunction("TO_NUMBER", StandardBasicTypes.INTEGER));
    }
}

registerFunction 을 가지고 방언을 등록해주면 되는데 2가지의 방법이 있다.

QueryDSL 의 경우, Expressions.stringTemplate 메서드와 같은 함수를 통해 위에서 작성한 함수들을 이용할 수 있다.