title: Hibernate and @JoinFormula: org.hibernate.mapping.Formula cannot be cast to org.hibernate.mapping.Column
body: <p>I'm trying to write a hibernate adapter for an old database schema. This schema does not have a dedicated id column, but uses about three other columns to join data.</p>
  
  <p>On some tables, I need to use coalesce. This is what I came up with so far:</p>
  
  <p>About the definition: </p>
  
  <ul>
  <li>A car can have elements, assigned by the car's user or by the car's group of users.</li>
  <li>If FORIGN_ELEMENT holds a user's name, definition will be 'u'</li>
  <li>If FORIGN_ELEMENT holds a group's name, definition will be 'g'</li>
  <li>This also means, one table (CAR_TO_ELEMENT) is misused to map cars to elements and cargroups to elements. I defined a superclass CarElement and subclasses CarUserElement and CarGroupElement.</li>
  <li>state is either "active" or an uninteresting string</li>
  <li>I set definitition and state elsewhere, we do not need to worry about this.</li>
  <li>Use DEP_NR on the join table. If it's zero, use USR_DEP_NR. I did this with <code>COALESCE(NULLIF())</code> successfully in native SQL and want to achieve the same in Hibernate with Pojos.</li>
  </ul>
  
  <p>Okay, here we go with the code:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Entity
  @Table(name="CAR")
  public class Car extends TableEntry implements Serializable {
      @Id
      @Column(name="DEP_NR")
      private int depnr;
  
      @Id
      @Column(name="USER_NAME")
      @Type(type="TrimmedString")
      private String username;
  
      @ManyToOne(fetch = FetchType.EAGER, targetEntity=CarGroup.class)
      @JoinColumns(value={ 
              @JoinColumn(name="GROUP_NAME"),
              @JoinColumn(name="DEP_NR"),
              @JoinColumn(name="state"),
      })
      private CarGroup group;
  
      @OneToMany(fetch=FetchType.EAGER, targetEntity=CarUserElement.class, mappedBy="car")
      private Set&lt;CarUserElement&gt; elements;
  }
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>@Entity
  @Table(name="CAR_GROUP")
  public class CarGroup extends TableEntry implements Serializable {
      @Id
      @Column(name="DEP_NR")
      private int depnr;
  
      @Id
      @Column(name="GROUP_NAME")
      @Type(type="TrimmedString")
      private String group;
  
      @ManyToOne(fetch = FetchType.EAGER, targetEntity=Car.class)
      @JoinColumns(value={ 
              @JoinColumn(name="GROUP_NAME"),
              @JoinColumn(name="DEP_NR"),
              @JoinColumn(name="state"),
      })
      private Set&lt;Car&gt; cars;
  
      @OneToMany(fetch=FetchType.EAGER, targetEntity=CarGroupElement.class, mappedBy="car")
      private Set&lt;CarGroupElement&gt; elements;
  }
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>@MappedSuperclass
  public class CarElement extends TableEntry {
      @Id
      @ManyToOne(fetch = FetchType.EAGER, targetEntity=Element.class)
      @JoinColumns(value={ 
              @JoinColumn(name="ELEMENT_NAME"),
              @JoinColumn(name="state"),
      })
      private Element element;
  }
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>@Entity
  @Table(name="CAR_TO_ELEMENT")
  public class CarUserElement extends CarElement {
      @Id
      @Column(name="DEFINITION")
      private char definition;
  
      @Id
      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumnsOrFormulas(value = {
          @JoinColumnOrFormula(formula=@JoinFormula(value="COALESCE(NULLIF(DEP_NR, 0), USR_DEP_NR)", referencedColumnName="DEP_NR")),
          @JoinColumnOrFormula(column=@JoinColumn(name="FORIGN_ELEMENT", referencedColumnName="USER_NAME")),
          @JoinColumnOrFormula(column=@JoinColumn(name="STATE", referencedColumnName="STATE"))
      })
      private Car car;
  
  }
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>@Entity
  @Table(name="CAR_TO_ELEMENT")
  public class CarGroupElement extends CarElement {
      @Id
      @Column(name="DEFINITION")
      private char definition;
  
      @Id
      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumnsOrFormulas(value = {
          @JoinColumnOrFormula(formula=@JoinFormula(value="COALESCE(NULLIF(DEP_NR, 0), USR_DEP_NR)", referencedColumnName="DEP_NR")),
          @JoinColumnOrFormula(column=@JoinColumn(name="FORIGN_ELEMENT", referencedColumnName="GROUP_NAME")),
          @JoinColumnOrFormula(column=@JoinColumn(name="STATE", referencedColumnName="STATE"))
      })
      private Car car;
  
  }
  </code></pre>
  
  <p>I tried all available versions of hibernate (from 3.5.1 [first version with <code>@JoinColumnsOrFormulas</code>] up to 4.x.x), but I always get this error:</p>
  
  <pre class="lang-java prettyprint-override"><code>Exception in thread "main" java.lang.ClassCastException: org.hibernate.mapping.Formula cannot be cast to org.hibernate.mapping.Column
      at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:351)
      at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1338)
      at org.hibernate.cfg.annotations.CollectionBinder.bindOneToManySecondPass(CollectionBinder.java:791)
      at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:719)
      at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:668)
      at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:66)
      at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1597)
      at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1355)
      at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737)
      at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1788)
  </code></pre>
  
  <p>Other hibernate users seem to have the same problem: They can't get it working with any version, see this thread and other stackoverflow questions:
  <a href="https://forum.hibernate.org/viewtopic.php?f=1&amp;t=1010559" rel="noreferrer">https://forum.hibernate.org/viewtopic.php?f=1&amp;t=1010559</a></p>
  
  <p>To be more complete, here's my TrimmedString Class:
  <a href="https://forum.hibernate.org/viewtopic.php?p=2191674&amp;sid=049b85950db50a8bd145f9dac49a5f6e#p2191674" rel="noreferrer">https://forum.hibernate.org/viewtopic.php?p=2191674&amp;sid=049b85950db50a8bd145f9dac49a5f6e#p2191674</a></p>
  
  <p>Thanks in advance!</p>
  
  <p>PS: It works with joining just these three colulmns with just one DEP-NR-Column (i.e. either DEP_NR <em>OR</em> USR_DEP_NR using just @JoinColumns). But I need this <code>coalesce(nullif())</code>.</p>