title: Problems in Spring when persistent Entities are composed using traits in groovy
body: <p>I have a Spring application that is java/groovy combination (Groovy 2.4.15, spring-data-jpa 2.0.9). I want to use “mixins” approach (in my case I wanna use groovy traits for implementation) to be able to compose persistent entities from CreatedAt, CreatedBy, Versioned, CretaedBy, SoftDeletable and a few more traits. It is not only about adding state properties with persistence annotations but also about related behavior that is implemented on the trait in a couple of cases. It is much more convenient to use traits/mixins instead of common inheritance since there are too many &quot;special cases&quot; when you need only some subset of these properties/behaviors.</p>
  <p>This would really help to clean up tons of code. There are multiple inheritance issues but when you are exactly aware of what you are doing then the technique is perfectly ok.</p>
  <p>Here is an example of trait implementation (Note that all classes are .groovy so getters and setters are generated when there is no field visibility modifier):</p>
  <pre><code>@MappedSuperclass
  trait CreatedAt implements ICreatedAt {
  
      @Column(name = &quot;CREATED_AT&quot;, nullable = false, updatable = false)
      @CreatedDate
      LocalDateTime createdAt;
  }
  </code></pre>
  <p>Here is an example of implementing class:</p>
  <pre><code>@Entity
  @EntityListeners([AuditingEntityListener.class])
  @Table(name = &quot;ROOM&quot;)
  class Room extends SequenceIdEntity&lt;Long&gt; implements
          CreatedAt,
          LastModifiedAt,
          CreatedBy,
          Versioned {
  
      @Column(name = &quot;NAME&quot;, nullable = false)
      String name;
      ...
      ...
  }
  </code></pre>
  <p>The problem:
  After some experiments I can say the ORM mapping behaves correctly. The problem begins when you implement Spring repositories. It just can’t find those fields from traits when you use them in methods that are used for query derivation from the name or when you use those fields in @Query annotation on the repository method.</p>
  <p>Why it doesn’t work:
  I was checking .class files generated from Entity implementing these traits and the reason is that private field names on the .class are modified (there is implementing trait full package prefix). I guess the reason is because of potential conflicts when implementing multiple traits countaining fields with similar name.  Getters and Setters are there unchanged. These changed names of fields are most likely the reason why Spring can’t scan that</p>
  <p>I also tried to place persistence annotations on getters and use @AccessType but it didn't help.</p>
  <pre><code>@MappedSuperclass
  trait CreatedAt implements ICreatedAt {
  
      private LocalDateTime createdAt;
  
      @Column(name = &quot;CREATED_AT&quot;, nullable = false, updatable = false)
      @CreatedDate
      @AccessType(AccessType.Type.PROPERTY)
      LocalDateTime getCreatedAt() {
          return this.createdAt
      }
  
      void setCreatedAt(LocalDateTime createdAt) {
          this.createdAt = createdAt
      }
  
  }
  </code></pre>
  <p>This attempt or the one above without @AccessType always ends up with exception Unable to locate Attribute  with the the given name [createdAt] on this ManagedType [cz.acrobits.csp.core.jpa.domain.SequenceIdEntity]</p>
  <p>Possible solutions:
  Maybe I am doing something wrong when using Getters and it is solvable this way. Any Ideas? Another way would be to convince Groovy so it does not change the field name on the generated/compiled class file. Is there a way to do it? Any other ideas?</p>
  <p>Any advice is welcomed, thank you,
  Lukas</p>