我將其追溯到getDatastoreClass,將null數據存儲類返回給createPerImplementationColumnsForReferenceField。當映射爲映射超類創建表時,NullPointerException
我已經嘗試過3.1.1,現在正在使用3.2.0-m4發行版,希望能解決我的問題。
RDBMSStoreManager#getDatastoreClass(String className, ClassLoaderResolver clr);
它返回一個空數據存儲類的
ReferenceMapping#createPerImplementationColumnsForReferenceField(boolean pk, boolean nullable, boolean serialised, boolean embedded, int fieldRole, ColumnMetaData[] columnMetaData, ClassLoaderResolver clr)
我使用ORM註釋映射,超類,這映射出的超沒有一個表的定義和我的兩個映射超類拋出這個異常。
499170 [http-bio-8080-exec-8] DEBUG DataNucleus.Datastore.Schema - Field [com.hp.vf.server.domain.AlertDefinition.isPublic] -> Column(s) ["ALERTDEFINITION"."ISPUBLIC"] using mapping of type "org.datanucleus.store.rdbms.mapping.java.BooleanMapping" (org.datanucleus.store.rdbms.mapping.datastore.SmallIntRDBMSMapping)
551964 [http-bio-8080-exec-8] DEBUG DataNucleus.Persistence - Managing Persistence of Class : com.hp.vf.analytics.shared.metric.Metric [Table : (none), InheritanceStrategy : subclass-table]
561964 [http-bio-8080-exec-8] ERROR DataNucleus.Datastore.Schema - An exception was thrown while adding/validating class(es) : null
java.lang.NullPointerException
at org.datanucleus.store.rdbms.mapping.java.ReferenceMapping.createPerImplementationColumnsForReferenceField(ReferenceMapping.java:452)
at org.datanucleus.store.rdbms.mapping.java.ReferenceMapping.prepareDatastoreMapping(ReferenceMapping.java:214)
at org.datanucleus.store.rdbms.mapping.java.ReferenceMapping.initialize(ReferenceMapping.java:110)
at org.datanucleus.store.rdbms.mapping.java.InterfaceMapping.initialize(InterfaceMapping.java:54)
在引用映射中,當嘗試執行getIdMapping()時dc爲空,我在調試器中驗證了這一點。
try
{
DatastoreClass dc = storeMgr.getDatastoreClass(implClass.getName(), clr);
m = dc.getIdMapping(); // DC is null
}
catch (NoTableManagedException ex)
{
// TODO Localise this message
throw new NucleusUserException("Cannot define columns for " + mmd.getFullFieldName() +
" due to " + ex.getMessage(), ex);
}
這是有問題的類文件。
public abstract class Metric implements IMetric {
/**
* Serialization ID
*/
private static final long serialVersionUID = 3806479436166940035L;
private Long id;
/**
* The name of the metric, this is not mandatory we have some metrics that
* may come back without names.
*/
protected String name;
/**
* This is an optional metric value that can be set by the script in order
* to add context to the execution of the metric.
*/
protected String context;
/**
* The list of violations associated with this metric.
*/
protected List<Violation> violations = null;
public Metric() {
violations = new ArrayList<Violation>();
}
/**
* Constructor that takes the name of the object and the value that it
* represents.
*
* @param name
* @param value
*/
public Metric(String name) {
this();
this.name = name;
}
/* (non-Javadoc)
* @see com.hp.vf.taskengine.shared.metric.IMetric#getName()
*/
@Override
public String getName() {
return name;
}
/* (non-Javadoc)
* @see com.hp.vf.taskengine.shared.metric.IMetric#setName(java.lang.String)
*/
@Override
public void setName(String name) {
this.name = name;
}
/**
* This is the context that represents the metric. This could have come from
* R and would be a Key:Value; pair of values used to calculate the value.
* For example if a metric was calculated for a product in houston for ISS
* the context may look like "ProdNum:1234;Factory:Houston;BUnit:ISS". This
* context is useful when chaining together tasks.
*
* @return String context used when chaining tasks together.
*/
public String getContext() {
return context;
}
/* (non-Javadoc)
* @see com.hp.vf.taskengine.shared.metric.IMetric#toString()
*/
public String toString() {
String debugString = "";
debugString += "Metric: " + name;
return debugString;
}
/* (non-Javadoc)
* @see com.hp.vf.taskengine.shared.metric.IMetric#hasMetricViolations()
*/
@Override
public boolean hasMetricViolations() {
return (violations != null && violations.size() > 0) ? true : false;
}
/* (non-Javadoc)
* @see com.hp.vf.taskengine.shared.metric.IMetric#getViolations()
*/
@Override
public List<IViolation> getViolations() {
return violations;
}
/* (non-Javadoc)
* @see com.hp.vf.taskengine.shared.metric.IMetric#setViolations(java.util.List)
*/
@Override
public void setViolations(List<IViolation> violations) {
this.violations = violations;
}
@Override
public Long getId() {
return id;
}
}
這裏是我的orm.xml文件的excert
<access>FIELD</access>
<mapped-superclass class="com.hp.vf.analytics.shared.metric.Metric" access="FIELD">
<attributes>
<basic name="name" />
<basic name="context" />
<one-to-many name="violations">
<cascade>
<cascade-all />
</cascade>
</one-to-many>
</attributes>
</mapped-superclass>
我做得不對或這是一個錯誤?
你有一些領域是一個接口(以及一個引用字段,所以可能是接口或可能是java.lang.Object),並且你不顯示具有此字段的類。何哼哼 – DataNucleus 2013-02-27 08:20:18
哇,對不起。當我發佈這個問題的時候,我已經筋疲力盡,不敢相信我沒有給課堂上課。我相信你是完全正確的,雖然我沒有看到增強器中的任何特定的增強功能,但啓用了調試功能後我可能錯過了它。我很確定我需要將目標實體添加到違規類的一對多中。但奇怪的是,它有50%的時間工作。我編寫了一個單元測試來保存一個擴展的度量類,並且它會在其他所有運行中成功完成。任何想法爲什麼這可能是? – 2013-02-27 13:08:51
推測違規是那裏的接口類型。不知道你的問題;我使用JPA,標記爲@OneToMany的接口類型的Set字段,並且一直在爲我工作,如http://www.datanucleus.org/products/accessplatform_3_2/jpa/orm/interfaces.html,但那樣做清楚地說明使用連接表並且是單向的 – DataNucleus 2013-02-27 13:49:02