Ответ 1
С session-objects-per-thread, если вы не используете объекты сеанса между несколькими потоками, вы будете в порядке.
Ошибка, которую вы получаете, не связана с вашим многопоточным использованием или вашим управлением сеансом. Ваше использование session.save()
, а также явно задание ID не совсем корректно.
Не видя вашего сопоставления для BlogPost
, его сложно сказать, но если вы сказали Hibernate использовать поле id
в качестве первичного ключа, и вы используете собственный генератор для первичных ключей, все, что вам нужно do:
session.beginTransaction();
session.persist(b);
session.flush(); // only needed if flush mode is "manual"
session.getTransaction().commit();
Hibernate заполнит идентификатор для вас, persist()
приведет к тому, что вставка произойдет в рамках транзакции (save()
не заботится о транзакциях). Если ваш режим флеша не настроен на ручной, вам не нужно вызывать flush()
, поскольку Transaction.commit()
будет обрабатывать это для вас.
Обратите внимание, что при persist()
идентификатор BlogPost не будет установлен до тех пор, пока сеанс не будет очищен, что отлично подходит для вашего использования здесь.
Для корректной обработки ошибок:
try {
session.beginTransaction();
try {
session.persist(b);
session.flush(); // only needed if flush mode is "manual"
session.getTransaction().commit();
} catch (Exception x) {
session.getTransaction().rollback();
// log the error
}
} catch (Exception x) {
// log the error
}
Кстати, я предлагаю сделать private BlogPost.setId()
или пакет видимым. Скорее всего, это ошибка реализации, если другой класс явно устанавливает идентификатор (опять же, предполагая собственный генератор, а id - как первичный ключ).