Pio*_*cki 7 hibernate jpa eclipselink jpa-2.0
我的@MapsId注释有问题@EmbeddedId.在Hibernate中运行代码时,我得到:
由以下原因引起:org.hibernate.PropertyAccessException:无法通过com.test.entities.EmployeeId.serverId的反射设置器设置字段值
但是,让我们从头开始......我有一个实体的复合主键,Employee它包含两个其他实体的外键(Server和Website).为了实现干净的设计,我在Employee实体中使用实体关系,这应该反映在EmployeeIdembeddable中.这个例子很简单,如下:
@Entity
public class Server implements Serializable {
@Id
@GeneratedValue
private int id;
private String url;
public Server() {}
public Server(String name) {
this.url = name;
}
}
Run Code Online (Sandbox Code Playgroud)
@Entity
public class Website implements Serializable {
@Id
@GeneratedValue
private int id;
private String name;
public Website() {}
public Website(String name) {
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
@Embeddable
public class EmployeeId implements Serializable {
protected int websiteId;
protected int serverId;
}
Run Code Online (Sandbox Code Playgroud)
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我有一些用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();
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我在这里没有做任何花哨的东西 - 只需在Employee对象中设置实体并坚持下去.据我所知,@MapsId注释应该反映注释实体的状态EmbeddedId.
现在的问题是,在EclipseLink中,一切都运行顺畅,实体被正确保存.当我将JPA 2.0提供程序更改为Hibernate(4.0 CR5)时,它会抛出一个PropertyAccessException:
例外在线程"主" javax.persistence.PersistenceException:org.hibernate.PropertyAccessException:无法设置通过在org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl com.test.entities.EmployeeId.serverId的反射设定部的字段值.的java:1353)在org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1281)在org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1287)在org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl .java:853)com.test.Standalone.executeTest(Standalone.java:101)at com.test.Standalone.main(Standalone.java:35)引起:org.hibernate.PropertyAccessException:无法设置字段值通过在org.hibernate.property.DirectPropertyAccessor $ DirectSetter.set(DirectPropertyAccessor.java:150)在org.hibernate.mapping.Component $ ValueGenerationPlan.execute(Component.java:436 com.test.entities.EmployeeId.serverId的反射设定器在org.hibe 在org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java)的org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:120)中的rnate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:121): 78)在org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:180)在org.hibernate.event.internal.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)at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:847)... 2更多引起:java.lang.NullPointerE xception在sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:36)在sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:57)在java.lang.reflect.Field.set(Field.java:657)在有机.hibernate.property.DirectPropertyAccessor $ DirectSetter.set(DirectPropertyAccessor.java:138)... 13更多
我不知道NullPointerException可能来自哪里 - 因为你可以看到所有实体属性都已设置.
我甚至不知道为什么地球上Hibernate需要一个二传手,但只是要确定我已经为各个领域(includng编号),提供制定者Employee,Website以及Server实体.正如所料 - 没有任何改变,Hibernate仍然找不到(已经存在)setter.
你认为它可能是一些错误,或者我只是不理解JPA 2.0合同的某些部分?
提前致谢!
Ric*_*ati 15
解决方案:遇到同样的问题,现在就开始工作了.
为了使它工作,EmployeeId你的Employee类应该在Employee的构造函数中实例化,或者在建立持久性之前在SessionBean中实例化.
否则,它会尝试填充embeddedid的值,并将其设置为null.
不确定这是否正常或者是否是JPA规范的错误实现.我认为后者因为你的PK的构造函数被定义而且hibernate应该能够自己调用它.
| 归档时间: |
|
| 查看次数: |
9126 次 |
| 最近记录: |