<p>I'm looking for a builder for <a href="http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html" rel="noreferrer">HQL</a> in Java. I want to get rid of things like:</p>

<pre><code>StringBuilder builder = new StringBuilder()
    .append("select stock from ")
    .append( Stock.class.getName() )
    .append( " as stock where stock.id = ")
    .append( id );
</code></pre>

<p>I'd rather have something like:</p>

<pre><code>HqlBuilder builder = new HqlBuilder()
    .select( "stock" )
    .from( Stock.class.getName() ).as( "stock" )
    .where( "stock.id" ).equals( id );
</code></pre>

<p>I googled a bit, and I couldn't find one.</p>

<p>I wrote a quick &amp; dumb <code>HqlBuilder</code> that suits my needs for now, but I'd love to find one that has more users and tests than me alone.</p>

<p>Note: I'd like to be able to do things like this and more, which I failed to do with the Criteria API:</p>

<pre><code>select stock
from com.something.Stock as stock, com.something.Bonus as bonus
where stock.someValue = bonus.id
</code></pre>

<p>ie. select all stocks whose property <code>someValue</code> points to <em>any</em> bonus from the Bonus table.</p>

<p>Thanks!</p>

[{'answer_id': 56866, 'author': 'sblundy', 'author_id': 4893, 'author_profile': 'https://Stackoverflow.com/users/4893', 'pm_score': 3, 'selected': False, 'text': '<p>Doesn\'t the <a href="http://www.hibernate.org/hib_docs/v3/reference/en/html/querycriteria.html" rel="noreferrer">Criteria API</a> do it for you? It looks almost exactly like what you\'re asking for. </p>\n'}, {'answer_id': 56883, 'author': 'Alex Argo', 'author_id': 5885, 'author_profile': 'https://Stackoverflow.com/users/5885', 'pm_score': 2, 'selected': False, 'text': '<p>It looks like you want to use the Criteria query API built into Hibernate. To do your above query it would look like this:</p>\n\n<pre><code>List&lt;Stock&gt; stocks = session.createCriteria(Stock.class)\n    .add(Property.forName("id").eq(id))\n    .list();\n</code></pre>\n\n<p>If you don\'t have access to the Hibernate Session yet, you can used \'DetachedCriteria\' like so:</p>\n\n<pre><code>DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class) \n    .add(Property.forName("id").eq(id));\n</code></pre>\n\n<p>If you wanted to get all Stock that have a Bonus with a specific ID you could do the following:</p>\n\n<pre><code>DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class)\n     .createCriteria("Stock")\n          .add(Property.forName("id").eq(id)));\n</code></pre>\n\n<p>For more infromation check out <a href="http://www.hibernate.org/hib_docs/reference/en/html/querycriteria.html" rel="nofollow noreferrer" title="Criteria Queries from Hibernate Documentation">Criteria Queries</a> from the Hibernate docs</p>\n'}, {'answer_id': 56937, 'author': 'sblundy', 'author_id': 4893, 'author_profile': 'https://Stackoverflow.com/users/4893', 'pm_score': 2, 'selected': False, 'text': '<p>@<a href="https://stackoverflow.com/questions/56843/looking-for-an-hql-builder-hibernate-query-language#56889">Sébastien Rocca-Serra</a>  </p>\n\n<pre><code>select stock\nfrom com.something.Stock as stock, com.something.Bonus as bonus\nwhere stock.bonus.id = bonus.id\n</code></pre>\n\n<p>That\'s just a join. Hibernate does it automatically, if and only if you\'ve got the mapping between <code>Stock</code> and <code>Bonus</code> setup and if <code>bonus</code> is a property of <code>Stock</code>. <code>Criteria.list()</code> will return <code>Stock</code> objects and you just call <code>stock.getBonus()</code>.</p>\n\n<p>Note, if you want to do anything like</p>\n\n<pre><code>select stock\nfrom com.something.Stock as stock\nwhere stock.bonus.value &gt; 1000000\n</code></pre>\n\n<p>You need to use <a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html#createAlias(java.lang.String,%20java.lang.String)" rel="nofollow noreferrer"><code>Criteria.createAlias()</code></a>. It\'d be something like</p>\n\n<pre><code>session.createCriteria(Stock.class).createAlias("bonus", "b")\n   .add(Restrictions.gt("b.value", 1000000)).list()\n</code></pre>\n'}, {'answer_id': 57100, 'author': 'sblundy', 'author_id': 4893, 'author_profile': 'https://Stackoverflow.com/users/4893', 'pm_score': 4, 'selected': True, 'text': '<p>@<a href="https://stackoverflow.com/questions/56843/looking-for-an-hql-builder-hibernate-query-language#57001">Sébastien Rocca-Serra</a><br>\nNow we\'re getting somewhere concrete. The sort of join you\'re trying to do isn\'t really possible through the Criteria API, but a sub-query should accomplish the same thing. First you create a <code>DetachedCriteria</code> for the bonus table, then use the <code>IN</code> operator for <code>someValue</code>.</p>\n\n<pre><code>DetachedCriteria bonuses = DetachedCriteria.forClass(Bonus.class);\nList stocks = session.createCriteria(Stock.class)\n    .add(Property.forName("someValue").in(bonuses)).list();\n</code></pre>\n\n<p>This is equivalent to</p>\n\n<pre><code>select stock\nfrom com.something.Stock as stock\nwhere stock.someValue in (select bonus.id from com.something.Bonus as bonus)\n</code></pre>\n\n<p>The only downside would be if you have references to different tables in <code>someValue</code> and your ID\'s are not unique across all tables. But your query would suffer from the same flaw.</p>\n'}, {'answer_id': 57141, 'author': 'Marcio Aguiar', 'author_id': 4213, 'author_profile': 'https://Stackoverflow.com/users/4213', 'pm_score': 2, 'selected': False, 'text': '<p>Criteria API does not provide all functionality avaiable in HQL. For example, you cannot do more than one join over the same column.</p>\n\n<p>Why don\'t you use <strong><a href="http://www.javalobby.org/java/forums/t33053.html" rel="nofollow noreferrer">NAMED QUERIES</a></strong>? The look much more clean:</p>\n\n<pre><code>Person person = session.getNamedQuery("Person.findByName")\n                             .setString(0, "Marcio")\n                             .list();\n</code></pre>\n'}, {'answer_id': 586392, 'author': 'Josh', 'author_id': 56887, 'author_profile': 'https://Stackoverflow.com/users/56887', 'pm_score': 2, 'selected': False, 'text': '<p>I wrote a GPL\'d solution for OMERO which you could easily build suited to your situation.</p>\n\n<ul>\n<li>Source: <a href="http://trac.openmicroscopy.org.uk/omero/browser/trunk/components/server/src/ome/tools/hibernate/QueryBuilder.java" rel="nofollow noreferrer">QueryBuilder.java</a></li>\n<li>Test: <a href="http://trac.openmicroscopy.org.uk/omero/browser/trunk/components/server/test/ome/server/utests/QueryBuilderMockTest.java" rel="nofollow noreferrer">QueryBuilderMockTest</a></li>\n</ul>\n\n<p>Usage:</p>\n\n<pre><code>QueryBuilder qb = new QueryBuilder();\nqb.select("img");\nqb.from("Image", "img");\nqb.join("img.pixels", "pix", true, false);\n\n// Can\'t join anymore after this\nqb.where(); // First\nqb.append("(");\nqb.and("pt.details.creationTime &gt; :time");\nqb.param("time", new Date());\nqb.append(")");\nqb.and("img.id in (:ids)");\nqb.paramList("ids", new HashSet());\nqb.order("img.id", true);\nqb.order("this.details.creationEvent.time", false);\n</code></pre>\n\n<p>It functions as a state machine "select->from->join->where->order", etc. and keeps up with optional parameters. There were several queries which the Criteria API could not perform (see <a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-879" rel="nofollow noreferrer">HHH-879</a>), so in the end it was simpler to write this small class to wrap StringBuilder. (Note: there is a ticket <a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-2407" rel="nofollow noreferrer">HHH-2407</a> describing a Hibernate branch which should unify the two. After that, it would probably make sense to re-visit the Criteria API)</p>\n'}, {'answer_id': 1835464, 'author': 'Chuck Deal', 'author_id': 121475, 'author_profile': 'https://Stackoverflow.com/users/121475', 'pm_score': 2, 'selected': False, 'text': '<p>Take a look at the search package available from the <a href="http://code.google.com/p/hibernate-generic-dao/" rel="nofollow noreferrer">hibernate-generic-dao</a> project.  This is a pretty decent HQL Builder implementation.</p>\n'}, {'answer_id': 1880122, 'author': 'Guillaume', 'author_id': 228689, 'author_profile': 'https://Stackoverflow.com/users/228689', 'pm_score': 2, 'selected': False, 'text': '<p>I know this thread is pretty old, but I also was looking for a HqlBuilder And I found this <a href="http://forge.abcd.harvard.edu/gf/project/screensaver/scmsvn/?action=browse&amp;path=%2Fbranches%2Ficcbl%2Ftrunk%2Fsrc%2Fedu%2Fharvard%2Fmed%2Fscreensaver%2Fdb%2Fhibernate%2FHqlBuilder.java&amp;view=markup" rel="nofollow noreferrer">"screensaver" project</a> <br/>\nIt is NOT a Windows screensaver, it\'s a \n"<em>Lab Information Management System (LIMS) for high-throughput screening (HTS) facilities that perform small molecule and RNAi screens.</em>"</p>\n\n<p>It contains an HQLBuilder that is looking quite good.\n<br/>Here is a sample list of available methods:       </p>\n\n<pre><code>...\nHqlBuilder select(String alias);\nHqlBuilder select(String alias, String property);\nHqlBuilder from(Class&lt;?&gt; entityClass, String alias);\nHqlBuilder fromFetch(String joinAlias, String joinRelationship, String alias);\nHqlBuilder where(String alias, String property, Operator operator, Object value);\nHqlBuilder where(String alias, Operator operator, Object value);\nHqlBuilder where(String alias1, Operator operator, String alias2);\nHqlBuilder whereIn(String alias, String property, Set&lt;?&gt; values);\nHqlBuilder whereIn(String alias, Set&lt;?&gt; values);\nHqlBuilder where(Clause clause);\nHqlBuilder orderBy(String alias, String property);\nHqlBuilder orderBy(String alias, SortDirection sortDirection);\nHqlBuilder orderBy(String alias, String property, SortDirection sortDirection);\nString toHql();\n...\n</code></pre>\n'}, {'answer_id': 2044946, 'author': 'Timo Westkämper', 'author_id': 252552, 'author_profile': 'https://Stackoverflow.com/users/252552', 'pm_score': 3, 'selected': False, 'text': '<p>For a type-safe approach to your problem, consider <a href="http://www.querydsl.com" rel="noreferrer">Querydsl</a>.</p>\n\n<p>The example query becomes</p>\n\n<pre><code>HQLQuery query = new HibernateQuery(session);\nList&lt;Stock&gt; s = query.from(stock, bonus)\n  .where(stock.someValue.eq(bonus.id))\n  .list(stock);\n</code></pre>\n\n<p>Querydsl uses APT for code generation like JPA2 and supports JPA/Hibernate, JDO, SQL and Java collections.</p>\n\n<p>I am the maintainer of Querydsl, so this answer is biased.</p>\n'}, {'answer_id': 8372768, 'author': 'ebelanger', 'author_id': 1028380, 'author_profile': 'https://Stackoverflow.com/users/1028380', 'pm_score': 3, 'selected': False, 'text': '<p>For another type-safe query dsl, I recommend <a href="http://www.torpedoquery.org">http://www.torpedoquery.org</a>.  The library is still young but it provides type safety by directly using your entity\'s classes.  This means early compiler errors when the query no longer applies before of refactoring or redesign.</p>\n\n<p>I also provided you with an example.  I think from your posts that you where trying to do a subquery restriction, so I based the exemple on that:</p>\n\n<pre><code>import static org.torpedoquery.jpa.Torpedo.*;\n\nBonus bonus = from(Bonus.class);\nQuery subQuery = select(bonus.getId());\n\nStock stock = from(Stock.class);\nwhere(stock.getSomeValue()).in(subQuery);\n\nList&lt;Stock&gt; stocks = select(stock).list(entityManager);\n</code></pre>\n'}, {'answer_id': 17545743, 'author': 'tglman', 'author_id': 810633, 'author_profile': 'https://Stackoverflow.com/users/810633', 'pm_score': 1, 'selected': False, 'text': '<p>Now are also available the standard <a href="http://www.ibm.com/developerworks/library/j-typesafejpa/" rel="nofollow">JPA Type Safe</a> query and an less standard but also good <a href="https://www.objectquery.org/" rel="nofollow">Object Query</a></p>\n\n<p>Examples:</p>\n\n<p>JPA Type Safe</p>\n\n<pre><code>EntityManager em = ...\nCriteriaBuilder qb = em.getCriteriaBuilder();\nCriteriaQuery&lt;Stock&gt; c = qb.createQuery(Stock.class);\nRoot&lt;Stock&gt; = c.from(Stock.class);\nPredicate condition = qb.eq(p.get(Stock_.id), id);\nc.where(condition);\nTypedQuery&lt;Stock&gt; q = em.createQuery(c); \nList&lt;Stock&gt; result = q.getResultList();\n</code></pre>\n\n<p>Object Query</p>\n\n<pre><code>EntityManager em = ...\nObjectQuery&lt;Stock&gt; query = new GenericObjectQuery&lt;Stock&gt;(Stock.class);\nStock toSearch = query.target();\nquery.eq(toSearch.getId(),id);\nList&lt;Stock&gt; res = (List&lt;Stock&gt;)JPAObjectQuery.execute(query, em);\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/56843', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2797/']