title: JPA Clean Architecture
body: <p>I'm refactoring a microservice according to <em>Clean Architecture</em>:</p>
  <p><a href="https://i.stack.imgur.com/38sT3.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/38sT3.jpg" alt="enter image description here" /></a></p>
  <p>Frameworks should be at the utmost layer. So I used the Adapter Pattern and Dependency Inversion to put
  <code>org.springframework.data.repository.CrudRepository</code> at the utmost layer. But how can I use <code>@Entity</code> (from <strong>J</strong>ava <strong>P</strong>ersistence <strong>A</strong>PI) to persist my entities, if entities are in the center and frameworks are at the utmost layer?</p>
  <hr />
  <p>Example:
  Demo-Entity:</p>
  <pre class="lang-java prettyprint-override"><code>import javax.persistence.Entity;
  import javax.persistence.Id;
  import javax.validation.constraints.NotNull;
  
  @Entity
  public class Demo implements Serializable {
      @Id
      @GeneratedValue
      private long id;
      
      @NotNull
      private String foo;
  
  }
  </code></pre>
  
  <p>GenericRepostioryInterface (in the Usecase Layer)</p>
  <pre class="lang-java prettyprint-override"><code>public interface CrudRepositoryInterface&lt;S,T&gt; {
      public &lt;U extends S&gt; U save(U u) ;    
      public &lt;U extends S&gt; Iterable&lt;U&gt; saveAll(Iterable&lt;U&gt; itrbl) ;    
      public Optional&lt;S&gt; findById(T id) ;    
      public boolean existsById(T id) ;    
      public Iterable&lt;S&gt; findAll() ;    
      public Iterable&lt;S&gt; findAllById(Iterable&lt;T&gt; itrbl) ;    
      public long count() ;    
      public void deleteById(T id) ;    
      public void delete(S t);    
      public void deleteAll(Iterable&lt;? extends S&gt; itrbl) ;    
      public void deleteAll() ;  
  }
  </code></pre>
  
  <p>Some usecase:</p>
  <pre class="lang-java prettyprint-override"><code>    @Autowired
      private CrudRepositoryInterface&lt;Demo,Long&gt; demoRepository;
      ...
      
      private void deleteAll(){
        this.demoRepository.deleteAll();
      }
      ...
  </code></pre>
  
  <p>Adapter (DB Layer)</p>
  <pre class="lang-java prettyprint-override"><code>public interface DemoRepositoryAdapter extends CrudRepository&lt;Demo,Long&gt;,CrudRepositoryInterface&lt;Demo,Long&gt;{    
  }
  </code></pre>
  
  <p>Config for Injection (I put that in the DB Package/Layer as well)</p>
  <pre class="lang-java prettyprint-override"><code>@Configuration
  public class InjectRepositoryConfig {    
      @Bean
      public CrudRepositoryInterface&lt;Demo,Long&gt; animalOwnerRepository(@Autowired DemoRepositoryAdapter demoRepositoryAdapter){
          return demoRepositoryAdapter;
      }
  }
  </code></pre>
  
  <hr />
  <p>This works fine so far but I'm unsure how to remove / replace / refactor JPA out of the core layer?</p>