gpt4 book ai didi

java - 使用 Hibernate 持久保存一个对象

转载 作者:行者123 更新时间:2023-11-30 08:08:34 25 4
gpt4 key购买 nike

我正在尝试使用 Hibernate 将对象存储到数据库中,但出现异常,并且我完全不知道原因。

我开发了两种方法:首先,使用 save/persist/merge 方法,如下所示:

sessionCARTIF.beginTransaction();
sessionCARTIF.save((Schedulers)object);
sessionCARTIF.getTransaction().commit();

在这种情况下,我在提交结果时抛出了异常。它表示交易已成功启动

其次,我尝试通过常见的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。不过,该查询已经通过数据库图形界面进行了测试,并且可以正常工作。

有什么想法吗?

提前致谢

最佳答案

有多种原因可能导致您收到有关事务未成功启动的错误。第一个也是最常见的一个是因为您尝试使用同一 session 执行多个事务(Hibernate session 通常是事务绑定(bind)的,当您提交时, session 将关闭,除非您将 auto_close_session 选项更改为)。

通常的模式是创建一个 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;
}
}

然后使用工厂为每个事务创建一个 session ,如下所示:

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 s并分别设置参数。这也会对您处理类型转换产生副作用,特别是对于日期,例如:

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 注入(inject)。

关于java - 使用 Hibernate 持久保存一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30730735/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com