我正在使用 Hibernate 和 JPA(我升级到最新的 Hibernate 版本 4.2.2)并且我遇到了一个奇怪的错误。“无法通过...的反射吸气剂获得字段值”
我正在使用 JPA、Hibernate 和继承。
我的代码。
AbstractGraphPropertyContainer.java
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="containertype", discriminatorType=DiscriminatorType.STRING)
@Table(name="graphcontainers")
public abstract class AbstractGraphPropertyContainer implements DataObject {
public AbstractGraphPropertyContainer(){
}
public AbstractGraphPropertyContainer(long id){
this.id = id;
}
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="containerid")
long id;
@Column(name = "searchable")
public boolean searchable = true;
@Transient
Map<String, String> properties = new Hashtable<String, String>();
@Transient
private boolean retrieved = false;
static PortalFactory factory = SQLGraphManager.factory;
public long getID(){
Hibernate.initialize(this);
return this.id;
}
public void delete(){
Session session = null;
try {
SessionFactory sFactory = SQLGraphManager.fac;
session = sFactory.getCurrentSession();
Transaction tr = session.beginTransaction();
//Save this object
session.delete(this);
tr.commit();
}catch(HibernateException he){
throw new RuntimeException(he);
}
}
public void save(){
if(this.id > 0){
this.update();
return;
}
Session session = null;
try {
SessionFactory sFactory = SQLGraphManager.fac;
session = sFactory.getCurrentSession();
Transaction tr = session.beginTransaction();
//Save this object
session.save(this);
tr.commit();
}catch(HibernateException he){
throw new RuntimeException(he);
}
}
public void update(){
Session session = null;
try {
SessionFactory sFactory = SQLGraphManager.fac;
session = sFactory.getCurrentSession();
Transaction tr = session.beginTransaction();
//Save this object
session.update(this);
tr.commit();
}catch(HibernateException he){
throw new RuntimeException(he);
}
}
}
SQLGraph.java
@Entity
@Table(name="graphs")
@PrimaryKeyJoinColumn(name="graphid")
@DiscriminatorValue("GRAPH")
public class SQLGraph extends AbstractGraphPropertyContainer implements Graph {
@Column(name="graph_name")
String name;
@Column(name="graph_description")
String description;
@Column(name="schemalocked")
boolean schemaLocked;
@Column(name="detached")
boolean detached;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="graphs_schemas",
joinColumns={@JoinColumn(name="graphid")},
inverseJoinColumns={@JoinColumn(name="schemaid")})
private Set<SQLGraphSchema> schemas = new TreeSet<SQLGraphSchema>();
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="graphs_objects",
joinColumns={@JoinColumn(name="graphid")},
inverseJoinColumns={@JoinColumn(name="objectid")})
private Set<SQLGraphObject> objects = new TreeSet<SQLGraphObject>();
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="graphs_relationships",
joinColumns={@JoinColumn(name="graphid")},
inverseJoinColumns={@JoinColumn(name="relationshipid")})
private Set<SQLGraphRelationship> relationships = new TreeSet<SQLGraphRelationship>();
}
SQLGraphAction.java
@Entity
@Table(name="zeusportalgraphactions_typemap")
@PrimaryKeyJoinColumn(name="actionid")
@DiscriminatorValue("ACTION")
public class SQLGraphAction extends SQLGraphRelation<Member, GraphObject> implements
GraphAction {
@ManyToOne
@JoinColumn(name="endobjectid")
SQLGraphObject endObject;
@ManyToOne
@JoinColumn(name="typeid")
SQLGraphActionType type;
}
SQLGraphObject.java
@Entity
@Table(name="graphobjects")
@PrimaryKeyJoinColumn(name="objectid")
@DiscriminatorValue("OBJECT")
public class SQLGraphObject extends AbstractGraphPropertyContainer implements
GraphObject {
@Column(name="label")
String label;
@ManyToOne
@JoinColumn(name="typeid")
SQLGraphObjectType type;
@OneToMany(mappedBy="startObject")
private Set<SQLGraphRelationship> relationships = new TreeSet<SQLGraphRelationship>();
@OneToMany(mappedBy="endObject")
private Set<SQLGraphRelationship> incRelationships = new TreeSet<SQLGraphRelationship>();
@OneToMany(mappedBy="endObject")
private Set<SQLGraphAction> actions = new TreeSet<SQLGraphAction>();
}
错误:
Caused by: java.lang.RuntimeException: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.enetexperience.zeusportal.sql.graph.SQLGraphObject.actions
at com.enetexperience.zeusportal.sql.graph.AbstractGraphPropertyContainer.save(AbstractGraphPropertyContainer.java:269)
at com.enetexperience.zeusportal.sql.graph.SQLGraphManager.createObject(SQLGraphManager.java:306)
at com.enetexperience.zeusportal.graph.GraphManagerProxy.createObject(GraphManagerProxy.java:191)
at com.enetexperience.zeusportal.graph.GraphManagerProxy.getObject(GraphManagerProxy.java:330)
at com.enetexperience.zeusportal.graph.GraphSearchManager.addToIndex(GraphSearchManager.java:181)
at com.enetexperience.zeusportal.graph.GraphSearchManager.updateIndex(GraphSearchManager.java:455)
... 3 more
Caused by: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.enetexperience.zeusportal.sql.graph.SQLGraphObject.actions
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:62)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValue(AbstractEntityTuplizer.java:630)
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValue(AbstractEntityPersister.java:4522)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:166)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:424)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:263)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:764)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:756)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:752)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
at sun.proxy.$Proxy80.save(Unknown Source)
at com.enetexperience.zeusportal.sql.graph.AbstractGraphPropertyContainer.save(AbstractGraphPropertyContainer.java:261)
... 8 more
Caused by: java.lang.IllegalArgumentException: Can not set java.util.Set field com.enetexperience.zeusportal.sql.graph.SQLGraphObject.actions to com.enetexperience.zeusportal.sql.graph.SQLGraphObject
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:376)
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:59)
... 30 more
我查看了 StackOverFlow 和其他来源以了解此错误的原因。但没有运气。保存 SQLGraphObject 时发生错误。显然它认为我正在尝试在保存时将 SQLGraphObject 对象分配给 Set 属性。
有趣的是,从同一个超类扩展而来的 SQLGraph 可以毫无问题地保存。
我假设有一些关于 SQLGraphObject 的东西导致它出错,但我看不出它和 SQLGraph 有什么不同。
更新:删除 SQLGraphObject 中的集合映射时,字符串和原始字段出现相同的错误。删除所有字段映射时,我会收到关于超类 AbstractGraphPropertyContainer.java 中的 id 和可搜索字段的相同错误。保存 SQLGraph 不会给我任何问题。