Исключение гибернации с @MapsId, @EmbeddedId

У меня проблема с аннотацией @MapsId и @EmbeddedId . При запуске кода в Hibernate я получаю:

Вызвано: org.hibernate.PropertyAccessException: не удалось установить значение поля установщиком отражения com.test.entities.EmployeeId.serverId

Но, давайте начнем с самого начала ...У меня есть составной первичный ключ для объекта Сотрудник , который состоит из внешних ключей для двух других объектов ( Сервер и Веб-сайт ). Чтобы иметь чистый дизайн, я использую отношения сущностей в сущности Employee, которые должны быть отражены во встраиваемом файле EmployeeId . Пример довольно прост и выглядит следующим образом:

@Entity
public class Server implements Serializable {

    @Id
    @GeneratedValue
    private int id;

    private String url;

    public Server() {}

    public Server(String name) {
        this.url = name;
    }
}

@Entity
public class Website implements Serializable {

    @Id
    @GeneratedValue
    private int id;

    private String name;

    public Website() {}

    public Website(String name) {
        this.name = name;
    }
}

@Embeddable
public class EmployeeId implements Serializable {

    protected int websiteId;
    protected int serverId;
}

@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;
    }
}

Теперь у меня есть простой тестовый метод, написанный на Java SE (обратите внимание, что это обычный класс, выполняемый из статического основного метода - это не класс JUnit) :

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();
}

Как видите, я здесь не делаю ничего особенного - просто устанавливаю сущности в объекте Employee и сохраняю его. Насколько я понимаю, аннотация @MapsId должна отражать состояние аннотированной сущности в EmbeddedId .

Теперь проблема в том, что в EclipseLink все работает плавно и сущности сохраняются должным образом. Когда я меняю поставщика JPA 2.0 на Hibernate (4.0 CR5), он вызывает исключение PropertyAccessException :

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.PropertyAccessException : не удалось установить значение поля с помощью установщика отражения com.test.entities.EmployeeId.serverId в org.hibernate.ejb.AbstractEntityManagerImpl.convert (AbstractEntityManagerImpl.java:1353) {{1 }} в org.hibernate.ejb.AbstractEntityManagerImpl.convert (AbstractEntityManagerImpl.java:1281) в org.hibernate.ejb.AbstractEntityManagerImpl.convert (AbstractEntityManager:12Impl.java ) в org.hibernate.ejb.AbstractEntityManagerImpl.persist (AbstractEntityManagerImpl.java: 853) в com.test.Standalone.executeTest (Standalone.java:101) в com.test.Standalone.main (Standalone.java:35) Причина: {{1 }} org.hibernate.PropertyAccessException: не удалось установить значение поля установщиком отражения com.test.entities.EmployeeId.serverId в org.hibernate.property.DirectPropertyAccessor $ DirectSetter.set ( DirectPropertyAccessor.java:150) в org.hibernate.mapping.Component $ ValueGenerationPlan.execute (Component.java:436) в org.hibernate. id.CompositeNestedGeneratedValueGenerator.generate (CompositeNestedGeneratedValueGenerator.java:121) в org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId (AbstractSaveEventListener.java} в {1: }} org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId (EJB3PersistEventListener.java:78) в org.hibernate.event.internal.DefaultPersistEventListener.entityIs80_Transient (DefaultListenerIs) { {1}} в org.hibernate.event.int ernal.DefaultPersistEventListener.onPersist (DefaultPersistEventListener.java:136) в org.hibernate.event.internal.DefaultPersistEventListener.onPersist (DefaultPersistEventListener.java:64) в { }} org.hibernate.internal.SessionImpl.firePersist (SessionImpl.java:729) в org.hibernate.internal.SessionImpl.persist (SessionImpl.java:705) в org.hibernate. internal.SessionImpl.persist (SessionImpl.java:709) в org.hibernate.ejb.AbstractEntityManagerImpl.persist (AbstractEntityManagerImpl.java:847) ... еще 2 Причина автор: java.lang.NullPointerException в sun.reflect.UnsafeFieldAccessorImpl.ensureObj (UnsafeFieldAccessorImpl.java:36) в sun.reflect.UnsafeIntegerFieldAccessorImpl.set (UnsafeIntegerFieldAccessorImpl.java:57) в java.lang.reflect.Field.set (Field.java:657) в org.hibernate.property.DirectPropertyAccessor $ DirectSetter.set (DirectPropertyAccessor. java: 138) ...Еще 13

Я не знаю, откуда могло появиться исключение NullPointerException - как вы можете видеть, все свойства объекта установлены.

Я даже не знаю , зачем Hibernate нужен сеттер , но на всякий случай я предоставил сеттеры для каждого поля (включая идентификаторы) для Сотрудника , Веб-сайт и Сервер сущности. Как и ожидалось - ничего не изменилось, и Hibernate все еще не может найти (уже существующий) установщик.

Как вы думаете, это может быть ошибка или я просто не понял какую-то часть контракта JPA 2.0?

Заранее спасибо!

7
задан Piotr Nowicki 2 November 2011 в 17:04
поделиться