我正在尝试使用Hibernate将对象存储到数据库中,但是我得到了一个异常,我完全迷失了原因。
我开发了两种方法:首先,使用save / persist / merge方法如下:
sessionCARTIF.beginTransaction();
sessionCARTIF.save((Schedulers)object);
sessionCARTIF.getTransaction().commit();
在这种情况下,提交结果时会抛出我获得的异常。它说the transaction was nos successfully started
。
其次,我尝试了常见的SQL查询,如下所示:
String sSQL = "INSERT INTO SCHEDULERS(SCHEDULER_ID, SCHEDULER_NAME, START_DATE,"
+ "FINISH_DATE, TIMER, EVENT_ID, BUILDING_ID, EVENT_PROPERTIES)"
+ " VALUES ("+object.getSchedulerId()+", '"+object.getSchedulerName()+"', "
+ "to_timestamp('"+object.getStartDate()+"','YYYY-MM-DD HH24:MI:SS.FF'), "
+ "to_timestamp('"+object.getFinishDate()+"','YYYY-MM-DD HH24:MI:SS.FF'), "
+ " '"+object.getTimer()+"', "+object.getEvents().getEventId()+", "
+ "'"+object.getBuildingId()+"', '"+object.getEventProps()+"');";
sessionCARTIF.createSQLQuery(sSQL).executeUpdate();
在第二种情况下,例外org.hibernate.exception.SQLGrammarException
。但是,该查询已经使用数据库图形界面进行了测试,并且可以正常运行。
任何想法??
提前致谢
答案 0 :(得分:1)
有几个原因可能导致您无法成功启动事务的错误。第一个也是最常见的一个是因为您尝试使用相同的会话执行多个事务(Hibernate会话通常是事务绑定,当您提交会话时,除非您将auto_close_session
选项更改为{{1 }})。
通常的模式是创建一个false
对象,根据需要创建SessionFactory
:
Session
然后使用工厂为每个事务创建一个会话,如下所示:
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
获得此错误的另一个原因是因为您拥有非事务性数据源或连接定义,或者您在数据库级别启用了自动提交或禁用了事务(某些DB需要特定的驱动程序或库来支持事务,尤其是分布式交易)。
SQL字符串生成错误的原因可能是由于您要连接到SQL字符串中的一个或多个参数的字符串转换而导致的。当你连接时,Java调用每个类的Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// work with the db
tx.commit();
}
catch (Exception e) {
if (tx != null) {
tx.rollback();
}
// Handle the exception, print message, etc.
} finally {
session.close();
}
方法,输出可能不是你所期望的(特别是日期和非字符串值)。要验证这是否是问题,请打印.toString()
字符串并检查实际生成的SQL并最终发布。
请注意,将值连接到SQL指令被认为是一种不好的做法,可能会导致SQL injection!最好使用PreparedStatement并分别设置参数。这也有为您处理类型转换的副作用,尤其是对于日期,例如:
sSQL
请注意,在这种情况下,您不必处理在字符串周围添加引号,也不需要处理日期格式,并且在这种情况下保证不能进行SQL注入。