title: Hibernate exception with @MapsId, @EmbeddedId
body: <p>I've got a problem with <code>@MapsId</code> annotation and <code>@EmbeddedId</code>. When running a code in Hibernate I get:</p>
  
  <blockquote>
    <p>Caused by: org.hibernate.PropertyAccessException: could not set a
    field value by reflection setter of
    com.test.entities.EmployeeId.serverId</p>
  </blockquote>
  
  <p>But, let's start from the beginning... I have a composite primary key for entity <code>Employee</code> which consists of foreign keys to two other entities (<code>Server</code> and <code>Website</code>). In order to have a clean design I use entity relationships in Employee entity which should be reflected in the <code>EmployeeId</code> embeddable. The example is quite simple and is as follows:</p>
  
  <pre><code>@Entity
  public class Server implements Serializable {
  
      @Id
      @GeneratedValue
      private int id;
  
      private String url;
  
      public Server() {}
  
      public Server(String name) {
          this.url = name;
      }
  }
  </code></pre>
  
  <hr>
  
  <pre><code>@Entity
  public class Website implements Serializable {
  
      @Id
      @GeneratedValue
      private int id;
  
      private String name;
  
      public Website() {}
  
      public Website(String name) {
          this.name = name;
      }
  }
  </code></pre>
  
  <hr>
  
  <pre><code>@Embeddable
  public class EmployeeId implements Serializable {
  
      protected int websiteId;
      protected int serverId;
  }
  </code></pre>
  
  <hr>
  
  <pre><code>@Entity
  public class Employee implements Serializable {
  
      @EmbeddedId
      private EmployeeId id;
  
      private String firstName;
  
      @ManyToOne
      @MapsId("serverId")
      private Server server;
  
      @OneToOne
      @MapsId("websiteId")
      private Website website;
  
      public Employee() {}
  
      public Employee(String firstName, Server server, Website website) {
          this.firstName = firstName;
          this.server = server;
          this.website = website;
      }
  }
  </code></pre>
  
  <p>Now I have some simple test method written in Java SE (note this is a regular class executed from static main method - it is <strong>not</strong> a JUnit class):</p>
  
  <pre><code>private void executeTest() {
      EntityManagerFactory emf = Persistence.createEntityManagerFactory("standaloneTests");
  
      EntityManager em = emf.createEntityManager();
      EntityTransaction tx = em.getTransaction();
  
      tx.begin();
  
      Server s = new Server("BigServer");
      em.persist(s);
  
      Website w = new Website("domain.com");
      em.persist(w);
  
      Employee e = new Employee("John", s, w);
      em.persist(e);
  
      tx.commit();
  
      em.close();
      emf.close();
  }
  </code></pre>
  
  <p>As you can see, I'm not doing any fancy stuff here - just set entities in the <code>Employee</code> object and persist it. As I understand, the <code>@MapsId</code> annotation should reflect the state of the annotated entity in the <code>EmbeddedId</code>.</p>
  
  <p>Now the problem is that in EclipseLink everything works smoothly and entities are properly persisted. When I change the JPA 2.0 provider to Hibernate (4.0 CR5) it throws me an <strong>PropertyAccessException</strong>:</p>
  
  <blockquote>
    <p>Exception in thread "main" javax.persistence.PersistenceException:
    org.hibernate.PropertyAccessException: could not set a field value by
    reflection setter of com.test.entities.EmployeeId.serverId    at
    org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1353)
      at
    org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1281)
      at
    org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1287)
      at
    org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:853)
      at com.test.Standalone.executeTest(Standalone.java:101)     at
    com.test.Standalone.main(Standalone.java:35) Caused by:
    org.hibernate.PropertyAccessException: could not set a field value by
    reflection setter of com.test.entities.EmployeeId.serverId    at
    org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:150)
      at
    org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:436)
      at
    org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:121)
      at
    org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:120)
      at
    org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
      at
    org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:180)
      at
    org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:136)
      at
    org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:64)
      at
    org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:729)
      at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:705)
      at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:709)
      at
    org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:847)
      ... 2 more Caused by: java.lang.NullPointerException    at
    sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:36)
      at
    sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:57)
      at java.lang.reflect.Field.set(Field.java:657)  at
    org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:138)
      ... 13 more</p>
  </blockquote>
  
  <p>I don't know where from the NullPointerException might come from - as you can see all entity properties are set.</p>
  
  <p>I don't even know <strong>why on earth Hibernate needs a setter</strong>, but just to be sure I've provided setters for every field (includng IDs) for <code>Employee</code>, <code>Website</code> and <code>Server</code> entities. As expected - nothing changed and Hibernate still cannot find (already present) setter.</p>
  
  <p>Do you think it might be some bug or I just didn't understand some part of the JPA 2.0 contract?</p>
  
  <p>Thanks in advance!</p>