title: What is the fastest findByName query with hibernate?
body: <p>I am sure I can improve the performance of the following findByName query of hibernate:</p>
  
  <pre><code>public List&lt;User&gt; findByName(String name) {
    session.createCriteria(User.class).add(Restrictions.eq("name", name)).list();
  }
  </code></pre>
  
  <p>The bottleneck is that findByName method and I cannot use the id instead.</p>
  
  <p>In my case I know that the name is unique but adding an Index annotation to the name attribute didn't improve the performance. I did the following:</p>
  
  <pre><code>class User {
    @Index(name = "nameIdx")
    private String name;      
  }
  </code></pre>
  
  <p>In which way should I improve it or even more important: in which ways should I improve it first? I will need the full object with all the collections (layz or not) and deps of this class.</p>
  
  <p>Or can I improve it, if I want several User objects (and know several names)?</p>
  
  <p><strong>Update1:</strong></p>
  
  <p>The @Index annotation didn't improve the performance, because the database already had an index, because of my unique constraint annotation:</p>
  
  <pre><code>@UniqueConstraint(columnNames = {"name"})
  </code></pre>
  
  <p><strong>Update2:</strong></p>
  
  <ol>
  <li><p>Read the answers carefully!</p></li>
  <li><p>With the help of the SQL logging I saw that the real issue was that a lot of update and insert statements were raised although I did not commit or flush the transaction.
  The reason behind that was that I did (in a loop):</p>
  
  <pre><code>User u = findByName(name);
  if(u == null) 
     attach(u = new User(name));
  </code></pre>
  
  <p>and so hibernate needs to flush the newly created users to the db before every findByName query. I solved this with my own cache workaround (LinkedHashMap).</p></li>
  <li><p>Another improvement I made through Jens Schauder's tip:</p>
  
  <pre><code>public Collection&lt;User&gt; findByNames(Collection&lt;String&gt; names) {
     return session.createCriteria(User.class).
            add(Restrictions.in("name", names)).list();
  }
  </code></pre></li>
  <li><p>A further improvement could be made when specifying some of the user collection as not lazy:</p>
  
  <pre><code>@LazyCollection(LazyCollectionOption.FALSE)
  </code></pre>
  
  <p><a href="https://stackoverflow.com/questions/1409523/hibernate-how-to-persist-a-new-item-in-a-collection-without-loading-the-entire/1409643#1409643">Read this answer</a> to get an even better option.</p></li>
  <li><p>The last and most important one for me is: replacing my SortedSet items with a list and doing the following in the getItems method:</p>
  
  <pre><code>Set set = new LinkedHashSet(items);
  items.clear();
  items.addAll(set);
  Collections.sort(items, itemComparator);
  return Collections.unmodifiableCollection(items);
  </code></pre>
  
  <p>with that, hibernate can work on the items collection (i.e. adding) without loading the entire collection from database.</p></li>
  </ol>
  
  <p><strong>@Pascal Thivent and @Jens Schauder</strong>: bunch of thanks! Sorry, that I can only accept one answer :-/</p>
  
  <p>Helpful Logging settings:</p>
  
  <pre><code>log4j.logger.org.hibernate.tool.hbm2ddl=INFO, StdoutApp
  log4j.logger.org.hibernate.SQL=INFO, StdoutApp
  # additionally provide the information which parameters will be bound:
  log4j.logger.org.hibernate.type=TRACE
  </code></pre>
  
  <p><a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-monitoring-metrics" rel="nofollow noreferrer">Another helpful link</a>.</p>