title: does lombok have side effects on jpa
body: <p>I am working on converting a jpa entity to use lombok. The resulting code is the following:</p>
  
  <pre><code>@Entity
  @Table(name = "TEST")
  @Data
  @NoArgsConstructor
  @AllArgsConstructor
  class Test {
     ...
     @Column(name = "FORMATTING")
     @Enumerated(EnumType.ORDINAL)
     private FormatType formatType;
     ...
  }
  </code></pre>
  
  <p>The resulting error message contains the following</p>
  
  <pre><code>Caused by: org.hibernate.HibernateException: Missing column: formatType in TEST
  </code></pre>
  
  <p>I am really not sure what to google here. (I  tried pasting everything before <code>formatType</code> into google - didn't see anything)</p>
  
  <h1>NOTE:</h1>
  
  <ol>
  <li><p>fields have been renamed and aspects which do not appear relevant have been omitted, for the sake of brevity and privacy. if something looks like a typo, it probably is. please let me know if you notice something so that i can address it.</p></li>
  <li><p>the 3 lines describing the field are unchanged from the code i'm working with </p></li>
  </ol>
  
  <h1>EDIT:</h1>
  
  <p>I just noticed this right before the error message</p>
  
  <pre><code>13:22:19,967 INFO  [org.hibernate.tool.hbm2ddl.TableMetadata] (ServerService Thread Pool -- 57) HHH000261: Table found: TABLE
  13:22:19,967 INFO  [org.hibernate.tool.hbm2ddl.TableMetadata] (ServerService Thread Pool -- 57) HHH000037: Columns: [..., formatType, ...]
  13:22:19,968 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 57) MSC000001: Failed to start service jboss.persistenceunit."...": org.jboss.msc.service.StartException in service jboss.persistenceunit."...": javax.persistence.PersistenceException: [PersistenceUnit: ...] Unable to build EntityManagerFactory
  </code></pre>
  
  <h1>Should be functional</h1>
  
  <pre><code>  @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    @Table(name = "PARENT")
  
    public abstract class Parent implements Serializable {
  
       private static final long serialVersionUID = 1;
       @Id
       @Column(name = "ID")
       @GeneratedValue
       private long id;
       @Column(name = "ENABLED")
       private boolean enabled;
    }
  
    @Entity
    @Table(name = "CHILD")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Child extends Parent {
       /** XXX: HERE BE DRAGONS */
       @Column(name = "ENUM_1")
       @Enumerated(EnumType.STRING)
       private Enum1 enum1;
       @Column(name = "ENUM_2")
       @Enumerated(EnumType.ORDINAL)
       private Enum2 enum2;
       /** XXX: NO MORE DRAGONS */
       @Column(name = "FREQUENCY")
       private String frequency;
       @Column(name = "EMPTY")
       private boolean empty;
       @Column(name = "MAX_SIZE")
       private int maxSize;
    }
    public enum Enum1 {
       A,
       B,
       C
    }
    public enum Enum2 {
       X,
       Y,
       Z
    }
  </code></pre>
  
  <p>I have rolled back the lombok changes, I would still like to know what the issue is, but there is no rush. Also, thanks to this lovely little bug i am about 4 hours behind so i may be a little slow on the responses.</p>
  
  <p>The pk of the child table is an fk to the parent table, and without lombok everything appears to work, despite the fact that the <code>Child</code> class has no id. </p>
  
  <p><strong>SOLUTION:</strong></p>
  
  <p>I completely forgot about asking this. Not long ago I revizited this problem. To explain the solution lets look at a slightly simplified version of the first example i included.</p>
  
  <pre><code>@Entity
  @Table(name = "TEST")
  @Setter
  @Getter
  class Test {
     ...
     @Column(name = "FORMATTING")
     @Enumerated(EnumType.ORDINAL)
     private FormatType formatType;
     ...
  }
  </code></pre>
  
  <p>It would appear that Lombok will give you this:</p>
  
  <pre><code>@Entity
  @Table(name = "TEST")
  class Test {
     ...
     @Column(name = "FORMATTING")
     @Enumerated(EnumType.ORDINAL)
     private FormatType formatType;
  
     public FormatType getFormatType() {
        return formatType;
     }
     public void setFormatType(FormatType formatType) {
        this.formatType = formatType;
     }
     ...
  }
  </code></pre>
  
  <p>Note that the annotations are still attached to the <em>field</em>. Now, I am not certain if it is just the version or implementation of JPA that we are using but I gather that if an accessor is defined jpa just ignores any annotations besides <code>@Column</code> (as well as any parameters specified for <code>@Column</code> - which is why jpa was looking for the wrong column name). So we actually need:</p>
  
  <pre><code>@Entity
  @Table(name = "TEST")
  class Test {
     ...
     private FormatType formatType;
  
     @Column(name = "FORMATTING")
     @Enumerated(EnumType.ORDINAL)
     public FormatType getFormatType() {
        return formatType;
     }
     public void setFormatType(FormatType formatType) {
        this.formatType = formatType;
     }
     ...
  }
  </code></pre>
  
  <p>After a great deal of confusion trying to find examples and fill in some specifics regarding how lombok does its thing (to be fair I am very easily confused) i discovered this little gem: <a href="https://projectlombok.org/features/experimental/onX" rel="noreferrer"><code>onMethod=@__({@AnnotationsHere})</code></a>. Utilizing this feature I came up with the following:</p>
  
  <pre><code>@Entity
  @Table(name = "TEST")
  @Setter
  class Test {
     ...
     @Getter(onMethod=@__({
           @Column(name = "FORMATTING"),
           @Enumerated(EnumType.ORDINAL)
        }))
     private FormatType formatType;
  
     ...
  }
  </code></pre>
  
  <p>And presto it works. Now that we have what is apparently the only available solution I would like to address the question we are all pondering at the moment: is that really any cleaner than just writing the method manually and attaching the annotations there? Answer: ... I have no idea. I am just happy I found a solution.</p>