2

Trying to pass column name as parameter but JPA sets it as a value surrounding it with single quotes.

@NamedNativeQueries({
    @NamedNativeQuery(
            name = "Genre.findAllLocalized",
            query = "SELECT "
                    + " CASE "
                    + "     WHEN ? IS NULL THEN genre_default"
                    + "     ELSE ? "
                    + " END localized_genre "
                    + "FROM genre ORDER BY localized_genre")
})

Then:

List<String> res = em.createNamedQuery("Genre.findAllLocalized")
                .setParameter(1, colName)
                .setParameter(2, colName)
                .getResultList();

The problem is that the column names being passed are taken as values so the result will return result list with repeated values of "col_name" instead of selecting the value of the column passed as parameter.

Is this achievable?

Esteban Rincon
  • 2,040
  • 3
  • 27
  • 44

1 Answers1

1

Basically it makes no sense to create a prepared query like this, how would you name that query anyway: "*"? So the short answer is: no.

  1. But you could create named queries dynamically if this matches your requirement:

    String colName = "colName";
    String query = "SELECT WHEN " + colName + " IS NULL THEN genre_default";
    Query query = entitymanager.createQuery(query);
    
  2. Probably using a criteria builder is more the way you want to use JPA (code from https://en.wikibooks.org/wiki/Java_Persistence/Criteria):

    // Select the employees and the mailing addresses that have the same address.
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery criteriaQuery = criteriaBuilder.createQuery();
    Root employee = criteriaQuery.from(Employee.class);
    Root address = criteriaQuery.from(MailingAddress.class);
    criteriaQuery.multiselect(employee, address);
    
    criteriaQuery.where( criteriaBuilder.equal(employee.get("address"), address.get("address"));
    Query query = entityManager.createQuery(criteriaQuery);
    List<Object[]> result = query.getResultList();
    
Marvin Emil Brach
  • 3,984
  • 1
  • 32
  • 62
  • that is a bad idea since you open the possibility of SQL Injection – H4F Sep 25 '19 at 16:34
  • @H4F: 1. If you are giving a user the option to create queries your architecture is in most cases more than questionable. 2. With the second way injection is completely impossible at all. – Marvin Emil Brach Sep 30 '19 at 19:56