Эта хрень возникает из за того что два потока пытаются одновременно изменить поля одной и той же ентити. Вот что пишут про это
http://www.firebirdfaq.org/faq151/ ,
http://edn.embarcadero.com/article/30213.
В целом есть два способа это побороть
1)В коде добавить синхронизацию
2)Разобраться с изоляцией транзакций.
Подробнее:
http://ru.wikipedia.org/wiki/Уровни_изолированности_транзакций
для хибернэйта они задаются параметром hibernate.connection.isolation в пропертях,
значения описаны в java.sql.Connection:
Наверняка:
для hibernate, в пропертях прописать: hibernate.connection.isolation=8
Выдержки из java.sql.Connection:
/**
* A constant indicating that transactions are not supported.
*/
int TRANSACTION_NONE
= 0;
/**
* A constant indicating that
* dirty reads, non-repeatable reads and phantom reads can occur.
* This level allows a row changed by one transaction to be read
* by another transaction before any changes in that row have been
* committed (a "dirty read"). If any of the changes are rolled back,
* the second transaction will have retrieved an invalid row.
*/
int TRANSACTION_READ_UNCOMMITTED = 1;
/**
* A constant indicating that
* dirty reads are prevented; non-repeatable reads and phantom
* reads can occur. This level only prohibits a transaction
* from reading a row with uncommitted changes in it.
*/
int TRANSACTION_READ_COMMITTED = 2;
/**
* A constant indicating that
* dirty reads and non-repeatable reads are prevented; phantom
* reads can occur. This level prohibits a transaction from
* reading a row with uncommitted changes in it, and it also
* prohibits the situation where one transaction reads a row,
* a second transaction alters the row, and the first transaction
* rereads the row, getting different values the second time
* (a "non-repeatable read").
*/
int TRANSACTION_REPEATABLE_READ = 4;
/**
* A constant indicating that
* dirty reads, non-repeatable reads and phantom reads are prevented.
* This level includes the prohibitions in
*
TRANSACTION_REPEATABLE_READ
and further prohibits the
* situation where one transaction reads all rows that satisfy
* a
WHERE
condition, a second transaction inserts a row that
* satisfies that
WHERE
condition, and the first transaction
* rereads for the same condition, retrieving the additional
* "phantom" row in the second read.
*/
int TRANSACTION_SERIALIZABLE = 8;