2013-02-27 88 views
0

我將其追溯到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> 

我做得不對或這是一個錯誤?

+1

你有一些領域是一個接口(以及一個引用字段,所以可能是接口或可能是java.lang.Object),並且你不顯示具有此字段的類。何哼哼 – DataNucleus 2013-02-27 08:20:18

+0

哇,對不起。當我發佈這個問題的時候,我已經筋疲力盡,不敢相信我沒有給課堂上課。我相信你是完全正確的,雖然我沒有看到增強器中的任何特定的增強功能,但啓用了調試功能後我可能錯過了它。我很確定我需要將目標實體添加到違規類的一對多中。但奇怪的是,它有50%的時間工作。我編寫了一個單元測試來保存一個擴展的度量類,並且它會在其他所有運行中成功完成。任何想法爲什麼這可能是? – 2013-02-27 13:08:51

+1

推測違規是那裏的接口類型。不知道你的問題;我使用JPA,標記爲@OneToMany的接口類型的Set字段,並且一直在爲我工作,如http://www.datanucleus.org/products/accessplatform_3_2/jpa/orm/interfaces.html,但那樣做清楚地說明使用連接表並且是單向的 – DataNucleus 2013-02-27 13:49:02

回答

0

我能夠使用Datanucleus提示解決問題。我有多個問題

問題
最明顯的和愚蠢的我的一部分

如果你有一個一對多或一對一一個使用您必須指定目標的接口-實體。

/** 
    * The list of violations associated with this metric. 
    */ 
    protected List<IViolation> violations = null; 
... 
    <one-to-many name="violations" 
     target-entity="com.vf.analytics.shared.metric.Violation"> 
     <cascade> 
      <cascade-all /> 
     </cascade> 
    </one-to-many> 

不要使用仿製藥,JPA規範不suppport他們
不知道DataNucleus將支持泛型,但它,但可能不推薦使用。

public MetricNumber< T extends Number> extends Metric implements IMetric { 
    T value; 
} 

如果擴展未註釋確保你將它添加到您的orm.xml中的實體

我沒有測試的一些對象,所以我認爲DataNucleus將不理會但他們似乎並非如此。我擴展了沒有註釋但尚未將它們添加到orm.xml的第三方類,這也導致我得到的空指針異常爲空。