2015-06-09 2 views
1

Я пытаюсь сохранить объект в базе данных с помощью Hibernate, но я получаю исключение, и я полностью потерял причину.Сохраняет объект с Hibernate

Я разработал два пути: во-первых, с помощью сохранения/сохраняться/слияния методов следующим образом:

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? i.e sessionCARTIF.openSession(); – smoggers

+0

Ваш запрос sql кажется неправильным. Просто попробуйте использовать в 'SYSO' –

+0

Используете ли вы весну? –

ответ

1

Есть несколько причин, почему вы могли бы получить ошибку о сделке не началась успешно. Первый и наиболее распространенный из них - это то, что вы пытаетесь выполнить более одной транзакции с тем же сеансом (сеансы Hibernate обычно связаны транзакциями, когда вы фиксируете сеанс, закрывается, если вы не измените опцию auto_close_session на 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; 
    } 
} 

Затем использовать фабрику для создания сеанса для каждой сделки, как это:

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 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-инъекция гарантированно будет невозможна в этом случае.

+0

Большое вам спасибо за ваш ответ. Если я правильно понял, ваше предложение при использовании чистого java.sql, правильно? Или это пример из структуры Hibernate? Кроме того, сессия закрывается каждый раз, когда я беру результат, не так ли? Поскольку мой драйвер является многопоточным, и я должен каждый раз фиксировать результаты, поэтому, если я хорошо вас понял, я должен открывать сессию каждый раз, когда мне приходится взаимодействовать с базой данных. –

+0

Я обновил свой ответ с примером кода о том, как создать фабрику сеансов и создать сеансы из него – EmirCalabuch

+0

Кроме того, для аргументов запроса мое предложение касается чистых вызовов JDBC, однако Hibernate поддерживает аналогичный механизм с именованными параметрами: https: // docs. jboss.org/hibernate/orm/3.2/api/org/hibernate/Query.html – EmirCalabuch

Смежные вопросы