title: One-to-One mappings of basic type, into a single class in Hibernate
body: <p>So the situation is as follows: there is an entity which needs to be connected with a dictionary. Imagine a following structure</p>
  
  <pre class="lang-sql prettyprint-override"><code>create table Address (
      addressId bigint not null,
      addressLine1 varchar(255),
      city varchar(255),
      country varchar(255),
      state varchar(255),
      zipCode varchar(255),
      primary key (addressId)
  )
  
  create table STATES_DICT (
      state_code varchar(255),
      state_fullname varchar(255), 
      primary key (state_code)
  )
  </code></pre>
  
  <p>I want to map both ADDRESS and STATE_DICTIONARY into a single entity.</p>
  
  <pre class="lang-java prettyprint-override"><code>@Entity
  @Table(name = "ADDRESS")
  public class Address implements Serializable {
  
      @Id
      @Column(name = "ADDRESSID")
      private int addressId;
  
      @Column(name = "ADDRESSLINE1")
      private String addressLine1;
  
      @Column(name = "STATE")
      private String state;
  
      //??? annotations
      private String fullStateName;
  
      @Column(name = "ZIPCODE")
      private String zipCode;
  
      @Column(name = "CITY")
      private String city;
  
      @Column(name = "COUNTRY")
      private String country;
      //... getters and setters
  }
  </code></pre>
  
  <p>For a pure SQL I'll run</p>
  
  <pre class="lang-sql prettyprint-override"><code>select a.ADDRESSID, a.ADDRESSLINE1, a.CITY, a.ZIPCODE, a.STATE, 
      d.STATE_FULLNAME, a.COUNTRY 
  from ADDRESS a, STATES_DICT d where a.STATE = d.STATE_CODE
  </code></pre>
  
  <p>but I'm having severe problems with mapping it with JPA. </p>
  
  <ol>
  <li>I cannot use @SecondaryTable because the tables are not mapped by primary keys</li>
  <li>The best I could get was:</li>
  </ol>
  
  <pre class="lang-java prettyprint-override"><code>    @ElementCollection
      @JoinTable(name="STATES_DICT", 
              joinColumns=@JoinColumn(name="STATE_CODE", referencedColumnName="STATE"))
      @Column(name = "STATE_FULLNAME")
      private Collection&lt;String&gt; fullStateName;
  </code></pre>
  
  <p>Downside is - the mapping is always one-to-one and the Collection brings confusion and the relation is more of one-to-one (many-to-one) not one-to-many.</p>
  
  <p>Any ideas? Is there an equivalent of @ElementCollection for one-to-one mappings?
  Dropping the @ElementCollection does not help. fullStateName field is expected to be in ADDRESS column - which is not the case. </p>
  
  <p>Some notes: 
  * I need those two to keep together in a single entity. 
  * I'm extending existing solution, need to add just this dictionary column
  * The entity is processed later on by some other service which runs through primitive types only. I'd rather not change the service, that's why adding a @OneToOne relation is not preferable</p>
  
  <p>Many thanks</p>
  
  <hr>
  
  <p>I'm extending the question with @SecondaryTable example - which didn't work for me.</p>
  
  <pre class="lang-java prettyprint-override"><code>@Entity
  @Table(name = "ADDRESS")
  @SecondaryTable(name="STATES_DICT", 
          pkJoinColumns=@PrimaryKeyJoinColumn(columnDefinition="STATE_CODE", referencedColumnName="STATE"))
  public class Address implements Serializable {
  
      @Id
      @Column(name = "ADDRESSID")
      private int addressId;
  
      @Column(name = "ADDRESSLINE1")
      private String addressLine1;
  
      @Column(name = "STATE")
      private String state;
  
      @Column(table="STATES_DICT", name = "STATE_FULLNAME")
      private String fullStateName;
  
      @Column(name = "ZIPCODE")
      private String zipCode;
  
      @Column(name = "CITY")
      private String city;
  
      @Column(name = "COUNTRY")
      private String country;
  
      //... getters and setters
  }
  </code></pre>
  
  <p>That caused a nasty exception of:
  Caused by: org.hibernate.AnnotationException: SecondaryTable JoinColumn cannot reference a non primary key</p>
  
  <hr>
  
  <p>For the record - I couldn't find a way to do this (and assumed it's simply not the way it should be done). I've gone with relation annotations (@ManyToOne, @OneToOne) and @JoinColumn - so the proper way. I've adjusted the further processing logic to treat @JoinColumn annotations in the same way it's working with @Column. It worked.</p>
  
  <p>The further processing is a security feature which suppresses values based on user roles and original database column names. That's why it was so important for me to stick with the @Column annotation</p>