2012-09-14 37 views
0

我試圖在Hibernate中使用下面的Criteria查詢拉記錄。休眠對字符串使用連字符的限制拋出assertionfailure異常

Security result = (Security) getSession().createCriteria(Security.class) 
     .add( Restrictions.eq("symbol", symbol)).uniqueResult(); 

符號屬性是唯一的varchar類型(股票代碼),符號參數是字符串。

通常這工作得很好,但只要符號在名稱中包含連字符(例如「C-U」),就會得到AssertionFailure異常。

任何想法我做錯了什麼或如何解決?


一些背景....

這發生在我存儲日內統計(股票目前的價格從雅虎拉)一噸的個股長事務的內部(證券)來自紐約證券交易所和納斯達克。

就這一點而言,幾百個證券已經通過循環。他們已經「保存」了,但交易尚未完成。在緩衝區(?)已滿之前,我將其關閉。只有當涉及到在符號中帶有連字符的安全性時,它纔會拋出此異常。

這裏的調用參數....

security = securityDAO.findBySymbol(record[0]); 

在SecurityDAO完整的方法.......

public Security findBySymbol(String symbol){ 
    log.debug("finding Security by symbol"); 
    try{ 

     Security result = 
      (Security) getSession().createCriteria(Security.class) 
     .add( Restrictions.eq("symbol", symbol)).uniqueResult(); 

     if (result == null) 
      return null; 

     return result; 
    } catch (RuntimeException re) { 
     log.error("Failed to find security by symbol.", re); 
     throw re; 
    } 
} 

拋出的異常...

org.hibernate.AssertionFailure: null id in com.securityscanner.hibernate.IntradayStat entry (don't flush the Session after an exception occurs) 
at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:78) 
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:187) 
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:143) 
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219) 
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99) 
at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:58) 
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:997) 
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1590) 
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306) 
at org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:328) 
at com.securityscanner.hibernate.SecurityDAO.findBySymbol(SecurityDAO.java:187) 
at com.securityscanner.ScanStatsTask.storeCurrentStats(ScanStatsTask.java:196) 
at com.securityscanner.ScanStatsTask.run(ScanStatsTask.java:99) 
at java.util.TimerThread.mainLoop(Timer.java:512) 
at java.util.TimerThread.run(Timer.java:462) 

安全性擴展AbstractSecurity ................................

/

** 
* AbstractSecurity entity provides the base persistence definition of the 
* Security entity. @author MyEclipse Persistence Tools 
*/ 

public abstract class AbstractSecurity implements java.io.Serializable { 

    // Fields 

    private Integer securityId; 
    private Exchange exchange; 
    private String name; 
    private String symbol; 
    private String securityType; 
    private String description; 
    private Boolean skip; 
    private Set dailyStats = new HashSet(0); 
    private Set intradayStats = new HashSet(0); 

    // Constructors 

    /** default constructor */ 
    public AbstractSecurity() { 
    } 

    /** full constructor */ 
    public AbstractSecurity(Exchange exchange, String name, String symbol, 
      String securityType, String description, Boolean skip, 
      Set dailyStats, Set intradayStats) { 
     this.exchange = exchange; 
     this.name = name; 
     this.symbol = symbol; 
     this.securityType = securityType; 
     this.description = description; 
     this.skip = skip; 
     this.dailyStats = dailyStats; 
     this.intradayStats = intradayStats; 
    } 

    // Property accessors 

    public Integer getSecurityId() { 
     return this.securityId; 
    } 

    public void setSecurityId(Integer securityId) { 
     this.securityId = securityId; 
    } 

    public Exchange getExchange() { 
     return this.exchange; 
    } 

    public void setExchange(Exchange exchange) { 
     this.exchange = exchange; 
    } 

    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getSymbol() { 
     return this.symbol; 
    } 

    public void setSymbol(String symbol) { 
     this.symbol = symbol; 
    } 

    public String getSecurityType() { 
     return this.securityType; 
    } 

    public void setSecurityType(String securityType) { 
     this.securityType = securityType; 
    } 

    public String getDescription() { 
     return this.description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public Boolean getSkip() { 
     return this.skip; 
    } 

    public void setSkip(Boolean skip) { 
     this.skip = skip; 
    } 

    public Set getDailyStats() { 
     return this.dailyStats; 
    } 

    public void setDailyStats(Set dailyStats) { 
     this.dailyStats = dailyStats; 
    } 

    public Set getIntradayStats() { 
     return this.intradayStats; 
    } 

    public void setIntradayStats(Set intradayStats) { 
     this.intradayStats = intradayStats; 
    } 

} 
+1

張貼堆棧跟蹤,也是安全類 – Baz1nga

+0

的代碼當然...我會添加到原來的職位... –

回答

1

帕特里克,錯誤不在選擇,但在此之前的某個地方。

Hibernate保留所有更新或創建對象的列表,當您刷新會話或執行任何其他強制刷新的操作(如select)時,它會將所有髒對象保存到數據庫。

從堆棧跟蹤看來,您已經保存/更新了IntradayStat的一個新實例,而沒有一個id,並且hibernate期待着一個。

+0

是的,當我回頭看我有同樣的懷疑。我會調查並報告。 感謝您的幫助! =) –

+0

是的。看起來這正是發生的事情。有一些無效的時間戳通過碰巧與符號連字符的證券一致。當它們被刷新時,數據庫拒絕插入它們並分配一個ID。我收緊了驗證和事務處理,並且運行現在已成功完成。再次感謝! –

相關問題