当前位置: 首页 > 面试题库 >

@ MapsId,@ EmbeddedId的休眠异常

霍鸣
2023-03-14
问题内容

我在@MapsId注释和上遇到了问题@EmbeddedId。在Hibernate中运行代码时,我得到:

引起原因:org.hibernate.PropertyAccessException:无法通过com.test.entities.EmployeeId.serverId的反射设置器设置字段值

但是,让我们从头开始…我有一个实体的复合主键,Employee它由指向其他两个实体(ServerWebsite)的外键组成。为了设计简洁,我在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编写的简单测试方法(请注意,这是从静态main方法执行的常规类-它 不是 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: 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

我不知道NullPointerException可能来自哪里-如您所见,所有实体属性都已设置。

我甚至不知道 为什么地球上Hibernate需要一个二传手 ,但只是要肯定我提供制定者,每场(includng的ID)
EmployeeWebsiteServer实体。如预期的那样-没有任何变化,并且Hibernate仍然找不到(已经存在)setter。

您是否认为这可能是某个错误,或者我只是不理解JPA 2.0合同的某些部分?

提前致谢!


问题答案:

看到这个问题。它只是说

如果实体包含以下条件,则可能引发org.hibernate.PropertyAccessException:

  1. 使用@EmbeddedId
  2. 在集合或关联属性/字段上使用@JoinTable,该属性或字段引用实体的另一个属性/字段。

如您所见,到目前为止Do not use @EmbeddedId,建议的唯一“解决方法”是,这很奇怪。



 类似资料:
  • 问题内容: 我有一个hibernate映射问题。我有以下两个数据库表(不允许更改数据库): 我试图为这些数据库表创建实体,但是我不知道如何映射表之间的连接。这是我的尝试(但这是错误的): 困难在于我想在列和一部分嵌入式Id列之间建立一个OneToMany连接。对这个问题有想法吗?(我正在使用hibernate4.0.1) 问题答案: 必须使用而不是使用来映射位置: 请注意,虽然这不是标准的JPA。

  • 问题内容: 我有一个“复杂”的问题。 我正在使用Hibernate / JPA与数据库进行事务。 我不是DBA,客户端使用了我的应用程序,即RESTful Web服务。我的问题是数据库已更改(不是很频繁,但仍在更改)。另外,客户端并不总是尊重我的应用程序的输入(长度,类型等)。发生这种情况时,Hibernate会引发异常。异常很难翻译和从日志中读取,因为它具有嵌套的异常并且由很多文本组成:就像我说

  • 问题内容: 有人可以在hibernate状态下向我解释吗?我很难理解它。 如果可以举一个例子来解释它,那就最棒了,并且它在哪种用例中最适用? 问题答案: 这是Object DB的一个很好的解释。 指定ManyToOne或OneToOne关系属性,该属性提供EmbeddedId主键,EmbeddedId主键内的属性或父实体的简单主键的映射。value元素指定关系属性所对应的组合键中的属性。如果实体的

  • 问题内容: 从Weblogic 11c切换到Weblogic 12c后,出现此异常: 我发现了有关该主题的其他问题,但是所有解决方案都是关于错误的库的(Vaadin 7-Bean Validation )。我认为我的hibernate-validator与bean验证器库匹配。这是我在WEB-INF / lib中拥有的: 可能是由其他依赖性引起的吗? 编辑 我目前在我的weblogic-appli

  • 问题内容: 我有一个复合主键的表,其中指的是实体 HolidayPackage 有 许多 到 一个 关系 HolidayPackageVariant 和 HolidayPackage 。 当我尝试在HolidayPackageVariant中进行复杂的PK映射时,出现以下错误: 最初的SessionFactory创建失败。 有人可以告诉我我在做什么错吗? 我的POJO如下所示: HolidayPa

  • 问题内容: 尝试将结果集强制转换为映射类时,我收到了hibernate类的类强制转换异常…我能够查看返回的结果集中的数据…但是它以Object []的形式返回我可以将Object []设置为List …我可以正确地进行hibernate映射吗?我从查询中获取了正确的数据,但映射不正确… 映射 映射类 参加班 主要 问题答案: 对于测试,我建议您在产生类强制转换异常的语句周围放置一个try-catc