[英]java.sql.SQLException: This function is not supported using HSQL and Spring
Can someone please tell me why am I geting java.sql.SQLException: This function is not supported using HSQL and Spring? 有人可以告诉我为什么我得到java.sql.SQLException:使用HSQL和Spring不支持此功能吗? I am trying to insert a new row into my database..
我正在尝试在数据库中插入新行。
Below is my DAO and I get the error on the mySession.save(message) line: 下面是我的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());
}
}
}
Here is my main class: 这是我的主要课程:
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());
}
}
Here is my DatabaseConfig: 这是我的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;
}
}
and here is what I am getting to the console: 这是我要进入控制台的内容:
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)
Here is my message model bean: 这是我的消息模型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
You can't use a String
with @GenerateValue
with the Strategy GenerationType.AUTO
since it uses sequence generator and those can't be used with non-numerical values. 您不能将带有
@GenerateValue
的String
与Strategy GenerationType.AUTO
使用,因为它使用序列生成器,并且不能与非数字值一起使用。 You have to set it yourself. 您必须自己设置。 Use an
Integer
or Long
if you want it to be generated for you. 如果要为您生成
Integer
请使用Integer
或Long
。
Or use an id generator that uses string values 或使用使用字符串值的id生成器
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
it was a version issues. 这是一个版本问题。 I updated the versions and now everything works
我更新了版本,现在一切正常
I had the same issue after I upgraded hibernate to version 4.2.8 .Looking in the logs, I noticed that the sql query generated by hibernate tried to insert a record with a null primary key. 将hibernate升级到4.2.8版本后,我遇到了同样的问题。在日志中,我发现hibernate生成的sql查询试图插入具有空主键的记录。 The field was annotated just with: @Id @GeneratedValue
该字段仅通过以下方式注释:@Id @GeneratedValue
Upgrading hsqldb to version 2.2.9 made this disappear just like Denis said and I am very thankful to him for the reply. 像Denis所说的那样,将hsqldb升级到2.2.9版可以使此消失,我非常感谢他的答复。
It seems very likely that this issue is related to attempting to use a Session which has already signaled an error. 该问题很可能与尝试使用已经发出错误信号的会话有关。 As Sotirios mentioned, it is a bad idea to catch exceptions in your DAO, and if you do, it is critical that you re-throw them.
如Sotirios所述,在DAO中捕获异常是一个坏主意,如果您这样做,则重新抛出异常至关重要。
Normally, once you catch a Hibernate exception, you must roll back your transaction and close the session as the session state may no longer be valid ( Hibernate core documentation ). 通常,一旦捕获到Hibernate异常,就必须回滚事务并关闭会话,因为会话状态可能不再有效( Hibernate核心文档 )。
If the Session throws an exception, including any SQLException, immediately rollback the database transaction, call Session.close() and discard the Session instance.
如果Session引发异常(包括任何SQLException),请立即回滚数据库事务,调用Session.close()并丢弃Session实例。 Certain methods of Session will not leave the session in a consistent state.
某些会话方法不会使会话保持一致状态。 No exception thrown by Hibernate can be treated as recoverable.
Hibernate抛出的异常不能被视为可恢复的。 Ensure that the Session will be closed by calling close() in a finally block.
通过在finally块中调用close()来确保关闭会话。
Since you're using Spring, most of that doesn't apply to you, but the exception message you are seeing indicates that the actual cause of your problem probably was related to catching an exception and then continuing to use the same session. 由于您使用的是Spring,因此大多数情况都不适用于您,但是您看到的异常消息表明问题的实际原因可能与捕获异常有关,然后继续使用同一会话。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.