title: Retrive repository by entity type in Java
body: <p>I'm writing Java program, which interacts with Db via Hibernate.</p>
  
  <p>All my persistent classes extend from common abstract class <code>Entity</code> which implements interface <code>IEntity</code>. For example:</p>
  
  <pre><code>public interface IEntity {
      long getId();
      void setId(long id);
  }
  
  public abstract class Entity implements IEntity {
      private long id;
      //get + set id
  }
  
  public class User extends Entity {
      private string name;
      //get + set name
  }
  
  public class Item extends Entity {
      private string description;
      //get + set description
  }
  </code></pre>
  
  <p>For operations with Db I created repository classes which extend from  <code>Repository&lt;T extends IEntity&gt;</code> with standard CRUD methods for all entities and this class implements interface <code>IRepository&lt;T extends IEntity&gt;</code>:</p>
  
  <pre><code>public interface IRepository&lt;T extends IEntity&gt; {
      void create(T object) throws JDBCException;
      //other CRUD operations
  }
  
  public abstract class Repository&lt;T extends IEntity&gt; implements IRepository&lt;T&gt; {
      private final Class&lt;T&gt; entityClass;
      protected final EntityManager entityManager;
  
      public Repository(Class&lt;T&gt; entityClass, EntityManager entityManager) {
          this.entityClass = entityClass;
          this.entityManager = entityManager;
      }
  
      @Override
      public void create(T object) throws JDBCException {
          entityManager.getTransaction().begin();
          entityManager.persist(object);
          entityManager.getTransaction().commit();
      }
      //other CRUD operations implementation
  }
  
  public class UserRepository extends Repository&lt;User&gt; {
      public UserRepository (EntityManager entityManager) {
          super(AmountUnit.class, entityManager);
      }
  }
  
  public class ItemRepository extends Repository&lt;Item&gt; {
      public ItemRepository (EntityManager entityManager) {
          super(AmountUnit.class, entityManager);
      }
  }
  </code></pre>
  
  <p>This structure worked well until I decided to create method to obtain specific repository by its entity class.
  I see this method as something like this:</p>
  
  <pre><code>public &lt;T extends IEntity, U extends IRepository&lt;T&gt;&gt; U getByType(T object) {
          // code here
      }
  </code></pre>
  
  <p>Let's say, that class <code>User extends Entity</code> and have repository class <code>UserRepository extends Repository&lt;User&gt;</code>
  I'm expecting, that this method should return Repository<code>for</code>User  object`.</p>
  
  <p>From my point of view this can be achieved in two ways:</p>
  
  <ol>
  <li>Elegant. Create method for <code>IRepository</code> - <code>Class&lt;T&gt; getEntityClass</code>
  and then compare classes of input and  result of getEntityClass</li>
  <li><p>Stupid. Make many <code>if/else</code> statements inside this method and return repository. <code>if(object instanceof A) return ARepository</code></p>
  
  <pre><code>public class Storage {
       private IRepository&lt;? extends IEntity&gt;[] repositories;
  
       public &lt;T extends IEntity, U extends IRepository&lt;T&gt;&gt; U getByTypeVar1(T object) {
                   for (IRepository&lt;?&gt; repo : repositories) {
                       if (object instanceof repo.getEntityClass ()) // cannot resolve getEntityClass 
                       return repo;
                   }
               }
  
       public &lt;T extends IEntity, U extends IRepository&lt;T&gt;&gt; U getByTypeVar2(T object) {
  
                   if (object instanceof UserRepository.getEntityClass ())
                   return UserRepository; //incompatible type
                   //more if else here
  
               }
           }
  </code></pre></li>
  </ol>
  
  <p>But both of these implementation are failed to compile. May be you have any ideas how to write this method correctly</p>