2015-06-09 115 views
1

我想存储一个对象到数据库使用休眠,但我得到一个异常,我完全失去了原因。坚持一个对象与休眠

我已经开发了两种方法:首先,使用保存/持续/合并方法如下:

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

你有BeginTransaction方法之前打开的会话?即sessionCARTIF.openSession(); – smoggers

+0

你的SQL查询似乎不正确formed.just尝试在'SYSO'中使用 – 2015-06-09 11:39:59

+0

你使用弹簧? –

回答

1

有几个原因,你可能会收到关于未成功启动事务的错误。第一个也是最常见的一个原因是您尝试在同一个会话中执行多个事务(Hibernate会话通常是事务绑定的,当您提交会话时会关闭,除非您将auto_close_session选项更改为false)。

通常的图案是创建一个SessionFactory对象需要创建Session S:

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; 
    } 
} 

然后使用工厂来对每一项交易创建会话,像这样:

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(); 
} 

另一个出现此错误的原因是因为您拥有非事务性数据源或连接定义,或者您在数据库级启用了自动提交功能,或者事务处于禁用状态(某些数据库需要特定的驱动程序或库来支持事务处理离子,尤其是分布式交易)。

SQL字符串产生错误的原因可能是由于将您连接到您的SQL字符串中的一个或多个参数的字符串转换为字符串所致。当你连接时,Java调用每个类的.toString()方法,并且输出不可能是你期望的(特别是使用日期和非字符串值)。要验证这是否是问题,请打印sSQL字符串并检查实际正在生成的SQL并最终发布该SQL。

请注意,将值连接成SQL指令被认为是不好的做法,可能会导致SQL injection!最好使用PreparedStatement,并分别设置参数。这也有处理类型转换为你的副作用,特别是对日期,例如:

PreparedStatement stmt = conn.prepareStatement("INSERT INTO SCHEDULERS(SCHEDULER_ID, SCHEDULER_NAME, START_DATE," 
    + "FINISH_DATE, TIMER, EVENT_ID, BUILDING_ID, EVENT_PROPERTIES)" 
    + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); 

stmt.setString(1, object.getSchedulerId()); 
stmt.setString(2, object.getSchedulerName()); 
stmt.setDate(3, object.getStartDate()); 
stmt.setDate(4, object.getFinishDate()); 
stmt.setString(5, object.getTimer()); 
stmt.setString(6, object.getEvents().getEventId()); 
stmt.setString(7, object.getBuildingId()); 
stmt.setString(8, object.getEventProps()); 

stmt.executeUpdate(); 

注意,在这种情况下,你不必采取把字串,报价照顾,不需要以处理日期格式,并且在这种情况下SQL注入保证不可能。

+0

非常感谢您的回答。如果我理解正确,你的建议是使用纯java.sql,对吧?或者它是Hibernate框架的一个例子吗?除此之外,每次我提交结果时会话都会关闭,不是吗?因为我的驱动程序是多线程的,所以每次都必须提交结果,因此,如果我理解得很好,每次必须与数据库交互时都必须打开会话。 –

+0

我用示例代码更新了我的答案,关于如何创建会话工厂以及从中实例化会话 – EmirCalabuch

+0

另外,对于查询参数,我的建议关注纯JDBC调用,但是Hibernate支持具有命名参数的类似机制:https:// docs。 jboss.org/hibernate/orm/3.2/api/org/hibernate/Query.html – EmirCalabuch