1

I would like to avoid having column names as strings in the code. Is there any other way to accomplish this?:

String query = "SELECT c.foo1.columnA, c.foo1.foo2.columnB FROM Table c";
session.createQuery(query).list();

I'm able to iterate over a column as string like c.foo1.foo2.columnB by splitting and getting the ClassMetadata, the property Type and other Hibernate functions until I reach the last element. However, I can't think a way to get a column string from Java beans, iterating through properties too.

IvanRF
  • 7,115
  • 5
  • 47
  • 71
  • 2
    My advice: leave your code as is. It's much more readable this way. Implement unit tests to make sure your queries are valid, and do what they're supposed to do. Use named queries so that they're validated at deployment time. – JB Nizet Jul 08 '15 at 15:08
  • But they're not column names. They're class property names of your entities. And you're not selecting from a specific table either, you're querying for entity instances. This reads like an X/Y problem - why exactly do you want to make the property names variable? You want to re-use the same query for different entities perhaps? – Gimby Jul 08 '15 at 15:19
  • Actually, I had to restructure some tables and columns in a DB. Thus, I had to change my Java beans. However, I also have to search through all the code for queries that use some changed column. Therefore, I wanted to know if there is a better way to approach this. – IvanRF Jul 08 '15 at 15:31
  • What about Criteria? – Victor Jul 08 '15 at 18:56

2 Answers2

1

Not sure what is the intention. Couple of thoughts

If you are worried about possibility of property names being wrong, current day IDEs does a good job by validating the property names in JPA queries

Object reflection can give you the property names. But not necessarily all properties are mapped to columns. You can look at this and use it along with bean property names via reflection.

Hope that helps.

Community
  • 1
  • 1
0

There is no way to achieve what you are looking for. But, if your concern is correctness of these queries and worry that the problem will not be known until the execution hits this, you could use NamedQuery

@Entity
@NamedQuery(
    name="findAllEmployeesByFirstName",
    queryString="SELECT OBJECT(emp) FROM Employee emp WHERE emp.firstName = 'John'"
)

public class Employee implements Serializable {
...
}

Usage

List employees = em.createNamedQuery("findAllEmployeesByFirstName").getResultList();

The benefit is that queries defined in NamedQuery annotations are compiled to actual SQL at start up time. So incorrect field references(typo etc) will cause a start up error and the application will not start.

Another option will be as mentioned in the other answer to trust in a good IDE to refactor all occurrences properly when you rename fields (Idea does a great job at this, so would any other IDE)

EDIT: I do not think there is any performance degradation with named queries. Rather it may appear to be faster as compiled queries are cached(very subjective)

Finally, its better to use the actual query as-is as mentioned in comments. It is far more readable and debug in its context. If you are concerned about correctness, unit-test the heck out of it and be confident.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
ring bearer
  • 20,383
  • 7
  • 59
  • 72
  • If by using `NamedQuery` I get start up errors, it will be a huge improvement to my code. I feel like string queries are prone to execution errors. Thanks! – IvanRF Jul 08 '15 at 16:00
  • Is there any hit on performance for the queries compilation at start up? – IvanRF Jul 08 '15 at 16:02