title: Referencing a static table without foreign key when persisting
body: <p>Let's say I have two entities (ommitted getters/setters):</p>
  
  <pre><code>@Entity
  @Table
  public class A {
  
      private Long id;
      private B b;
      private String details;
  
      @SequenceGenerator(name = "auto_gen", sequenceName = "a_sequence", allocationSize = 1)
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "auto_gen")
      @Column(name="id",updatable = false,nullable = false)
      @Id
      public Long getId(){return id;}
  
      @OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
      @JoinColumn(name = "a_id")
      public B getB(){
          return b;
      }
  
  }
  
  
  @Entity
  @Table
  public class B {
      @Id
      @GenericGenerator(name="gen",strategy = "BIdentityGenerator")
      @GeneratedValue(generator = "gen")
      private Long id;
      @Column
      private String reason;
      @Column
      private Boolean requiresDetails;
  }
  </code></pre>
  
  <p>And the two tables are linked like so:</p>
  
  <pre><code>Table A
  -------
  id
  b_id (foreign key to primary key in B)
  details
  
  Table B
  -------
  id
  reason (unique)
  </code></pre>
  
  <p>Table B holds static data, so new rows should never be inserted.
  Given I have a new object A and an entity relationship to an existing db object B, I would like to persist A as a new row and link to an existing row for table B. I would also like to persist A without having the id of B beforehand, only the unique <code>reason</code> value.</p>
  
  <p>This scenario is fine if I manually provide an id for B before persisting A, but coding this way seems a bit cumbersome. I was wondering if there was a way to do it through a id generator to implicitly set the id of B given the value of <code>reason</code> in the database.
  I have tried using GenericGenerator to generate the id (see below); however, this has the problem where it assumes the generated value is a completely new generated id and violates the primary key constraint. I have also considered using entity listeners, but documentations states that they shouldn't call <code>EntityManager</code>.</p>
  
  <pre><code>public class BIdentityGenerator implements IdentifierGenerator {
  
      private static final String QUERY = "SELECT id FROM b WHERE reason = ?";
      private static Logger log = LoggerFactory.getLogger(BIdentityGenerator.class);
  
      @Override
      public Serializable generate(SharedSessionContractImplementor session, Object o) throws HibernateException {
  
          if (o instanceof B) {
              B b = (B) o;
              if (b.getReason() == null || b.getReason().isEmpty()) {
                  throw new HibernateException("No reason provided.");
              }
              try {
                  Connection connection = session.connection();
                  PreparedStatement statement = connection.prepareStatement(QUERY);
                  statement.setString(1, b.getReason());
                  ResultSet resultSet = statement.executeQuery();
                  if (resultSet.next()) {
                      long id = resultSet.getLong("id");
                      return id;
                  } else {
                      throw new HibernateException(String.format("No row with reason %s exists.", b.getReason()));
                  }
              } catch (SQLException e) {
                  throw new HibernateException(String.format("Unable to retrieve reason %s", b),e);
              }
          } else {
              throw new HibernateException("BIdentityGenerator only supports B.");
          }
  
      }
  }
  </code></pre>