2013-04-26 44 views
1

有人可以告訴我爲什麼我geting java.sql.SQLException:這個函數不支持使用HSQL和Spring?我試圖插入新行到我的數據庫..java.sql.SQLException:這個函數不支持使用HSQL和Spring

下面是我的DAO和我上mySession.save(消息)行錯誤:

@Transactional 
@Repository 
public class MessageDaoImpl implements MessageDao 
{ 


    private Log log = null; 
    @Autowired 
    private SessionFactory sessionFactory; 

    public MessageDaoImpl() 
    { 
     super(); 
     log = LogFactory.getLog(MessageDaoImpl.class); 

    } 

    @SuppressWarnings("unchecked") 
    @Transactional(readOnly = true, propagation = Propagation.REQUIRED) 
    public List<Message> listMessages() 
    { 
     try 
     { 
      return (List<Message>) sessionFactory.getCurrentSession() 
        .createCriteria(Message.class).list(); 

     } catch (Exception e) 
     { 
      log.fatal(e.getMessage()); 
      return null; 
     } 
    } 


    @SuppressWarnings("unchecked") 
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED) 
    public void SaveOrUpdateMessage(Message message) 
    { 
     try 
     { 
      Session mySession = sessionFactory.getCurrentSession(); 
      mySession.save(message); 
      mySession.flush(); 
     } catch (Exception e) 
     { 
      log.fatal(e.getMessage()); 
     } 
    } 


} 

這裏是我的主類:

public static void main(String[] args) 
    { 
     ApplicationContext context = new AnnotationConfigApplicationContext(HelloWorldConfig.class); 


     MessageService mService = context.getBean(MessageService.class); 

     HelloWorld helloWorld = context.getBean(HelloWorld.class); 

     /** 
     * Date: 4/26/13/9:26 AM 
     * Comments: 
     * 
     * I added Log4J to the example. 
     */ 

     LOGGER.debug("Message from HelloWorld Bean: " + helloWorld.getMessage()); 

     Message message = new Message(); 
     message.setMessage(helloWorld.getMessage()); 
     // 
     mService.SaveMessage(message); 



     helloWorld.setMessage("I am in Staten Island, New York"); 


     LOGGER.debug("Message from HelloWorld Bean: " + helloWorld.getMessage()); 
    } 
} 

這裏是我的DatabaseConfig:

public class DatabaseConfig 
{ 

    private static final Logger LOGGER = getLogger(DatabaseConfig.class); 


    @Autowired 
    Environment env; 

    @Bean 
    public DataSource dataSource() { 

     EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); 
     EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.HSQL). 
     addScript("schema.sql").build(); 

     return db; 
    } 


    @Bean 
    public DataSource hsqlDataSource() { 

     BasicDataSource ds = new BasicDataSource(); 


     try { 
      ds.setDriverClassName("org.hsqldb.jdbcDriver"); 
      ds.setUsername("sa"); 
      ds.setPassword(""); 
      ds.setUrl("jdbc:hsqldb:mem:mydb"); 
     } 
     catch (Exception e) 
     { 
      LOGGER.error(e.getMessage()); 
     } 
     return ds; 



    } 

    @Bean 
    public SessionFactory sessionFactory() 
    { 

     LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean(); 
     factoryBean.setDataSource(hsqlDataSource()); 
     factoryBean.setHibernateProperties(getHibernateProperties()); 
     factoryBean.setPackagesToScan(new String[]{"com.xxxxx.HelloSpringJavaBasedJavaConfig.model"}); 

     try 
     { 
      factoryBean.afterPropertiesSet(); 
     } catch (IOException e) 
     { 
      LOGGER.error(e.getMessage()); 
      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
     } 


     return factoryBean.getObject(); 
    } 

    @Bean 
    public Properties getHibernateProperties() 
    { 
     Properties hibernateProperties = new Properties(); 

     hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); 
     hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql")); 
     hibernateProperties.setProperty("hibernate.use_sql_comments", env.getProperty("hibernate.use_sql_comments")); 
     hibernateProperties.setProperty("hibernate.format_sql", env.getProperty("hibernate.format_sql")); 
     hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); 

     hibernateProperties.setProperty("hibernate.generate_statistics", env.getProperty("hibernate.generate_statistics")); 

     hibernateProperties.setProperty("javax.persistence.validation.mode", env.getProperty("javax.persistence.validation.mode")); 

     //Audit History flags 
     hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", env.getProperty("org.hibernate.envers.store_data_at_delete")); 
     hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", env.getProperty("org.hibernate.envers.global_with_modified_flag")); 

     return hibernateProperties; 
    } 

    @Bean 
    public HibernateTransactionManager hibernateTransactionManager() 
    { 
     HibernateTransactionManager htm = new HibernateTransactionManager(); 
     htm.setSessionFactory(sessionFactory()); 
     htm.afterPropertiesSet(); 
     return htm; 
    } 


} 

,這裏是我所得到的控制檯:

Exception in thread "main" org.hibernate.AssertionFailure: null id in com.xxx.HelloSpringJavaBasedJavaConfig.model.Message entry (don't flush the Session after an exception occurs) 

這是我的消息模型bean:

@Entity 
@Table(name = "messages") 
public class Message 
{ 

    @Id 
    @Column(name = "id") 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private String id; 

    @Column(name = "message") 
    private String message; 

    public String getId() 
    { 
     return id; 
    } 

    public void setId(String id) 
    { 
     this.id = id; 
    } 

    public String getMessage() 
    { 
     return message; 
    } 

    public void setMessage(String message) 
    { 
     this.message = message; 
    } 

    @Override 
    public String toString() 
    { 
     return "Message{" + 
       "id='" + id + '\'' + 
       ", message='" + message + '\'' + 
       '}'; 
    } 
} 
+0

你有一個'null'編號。顯示你的Message類的實現。另外,不要在你的道具中發現異常。 – 2013-04-26 16:27:14

+0

@SotiriosDelimanolis ID是「@GeneratedValue(strategy = GenerationType.AUTO)」,所以我沒有把它放在它的值 – SJS 2013-04-26 16:31:43

+0

我剛剛在github上發佈源代碼,所以你可以試試它 – SJS 2013-04-26 16:53:19

回答

1

你不能用@GenerateValue因爲它使用了序列發生器和那些不能與非數字被用來使用String與戰略GenerationType.AUTO值。你必須自己設定。如果您想讓它爲您生成,請使用IntegerLong

Hibernate docs

或使用使用字符串的ID生成值

@Id 
@GeneratedValue(generator="system-uuid") 
@GenericGenerator(name="system-uuid", strategy = "uuid") 
+0

多數民衆贊成沒有問題,但我發佈在github上的源,所以你可以試試 – SJS 2013-04-26 16:53:02

+0

@SJS什麼是告訴你,這不是問題? – 2013-04-26 17:39:49

0

這似乎很可能,這個問題涉及到試圖使用它已經標誌着一個錯誤會話。正如Sotirios所說,在DAO中捕獲異常是一個壞主意,如果你這樣做,重新拋出它是至關重要的。

通常情況下,一旦捕獲到Hibernate異常,您必須回退事務並關閉會話,因爲會話狀態可能不再有效(Hibernate core documentation)。

如果會話拋出異常,包括任何SQLException,立即回滾數據庫事務,調用Session.close()並放棄Session實例。 Session的某些方法不會使會話保持一致的狀態。 Hibernate引發的異常可以視爲可恢復。通過在finally塊中調用close()來確保Session被關閉。

由於您使用的是Spring,因此大部分內容並不適用於您,但是您看到的異常消息表明您的問題的實際原因可能與捕獲異常並繼續使用有關同一屆會議。

1

這是一個版本問題。我更新了版本,現在一切正常

9

這涉及到HSQL的使用的版本可能是版本問題,造成了1.8與Hibernate 4.需要使用2.2.9,而不是

1

我有同樣的問題後,我將Hibernate升級到4.2.8版。查看日誌,我注意到由hibernate生成的sql查詢嘗試插入帶有空主鍵的記錄。該字段僅用以下註解:@Id @GeneratedValue

將hsqldb升級到版本2.2.9使其消失,就像Denis所說的那樣,我非常感謝他的回覆。

相關問題