簡體   English   中英

java.sql.SQLException:使用HSQL和Spring不支持此功能

[英]java.sql.SQLException: This function is not supported using HSQL and Spring

有人可以告訴我為什么我得到java.sql.SQLException:使用HSQL和Spring不支持此功能嗎? 我正在嘗試在數據庫中插入新行。

下面是我的DAO,我在mySession.save(message)行上收到錯誤:

@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 + '\'' +
                '}';
    }
}

這與所使用的hsql的版本有關,可能導致問題的版本是休眠4的1.8。需要改用2.2.9

您不能將帶有@GenerateValueString與Strategy GenerationType.AUTO使用,因為它使用序列生成器,並且不能與非數字值一起使用。 您必須自己設置。 如果要為您生成Integer請使用IntegerLong

休眠文檔

或使用使用字符串值的id生成器

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

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

將hibernate升級到4.2.8版本后,我遇到了同樣的問題。在日志中,我發現hibernate生成的sql查詢試圖插入具有空主鍵的記錄。 該字段僅通過以下方式注釋:@Id @GeneratedValue

Denis所說的那樣,將hsqldb升級到2.2.9版可以使此消失,我非常感謝他的答復。

該問題很可能與嘗試使用已經發出錯誤信號的會話有關。 如Sotirios所述,在DAO中捕獲異常是一個壞主意,如果您這樣做,則重新拋出異常至關重要。

通常,一旦捕獲到Hibernate異常,就必須回滾事務並關閉會話,因為會話狀態可能不再有效( Hibernate核心文檔 )。

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

由於您使用的是Spring,因此大多數情況都不適用於您,但是您看到的異常消息表明問題的實際原因可能與捕獲異常有關,然后繼續使用同一會話。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM