Я занимаюсь созданием составного первичного ключа с помощью @GenericGenerator
.В случае одновременных вызовов иногда происходит сбой с ConstraintViolationException
.Я бы предпочел установить механизм повтора вместо того, чтобы проваливать некоторые из моих одновременных вызовов POST.Проблема в том, что я не смог принудительно повторно сгенерировать ключа.
Я попытался снова вызвать JpaRepository#saveAndFlush
с тем же объектом при неудаче, но @Id
остаетсято же самое после того, как оно было сгенерировано.
Есть ли общий способ для retrigger @Id
генерация для сущности при ConstraintViolationException
?
Мое определение сущности:
@Entity
@Table(name = "some_entity")
public class SomeEntity {
@Embeddable
public static class SomeEntityId implements Serializable {
private int year;
private int number;
// (...)
}
@EmbeddedId
@GenericGenerator(name = "some_entity_id", strategy = "SomeEntityIdGenerator")
@GeneratedValue(generator = "some_entity_id")
private SomeEntityId id;
// (...)
}
Генератор:
public class SomeEntityIdGenerator implements IdentifierGenerator {
@Override
public Serializable generate(SharedSessionContractImplementor session,
Object object) throws HibernateException {
int year = getYear(object);
int number = getNumber(year, session.connection());
return new SomeEntity.SomeEntitytId(year, number);
}
private static int getNumber(int year, Connection connection) {
try {
PreparedStatement statement = connection.prepareStatement(
"select max(request_number) from some_entity where year = ?");
statement.setInt(1, year);
ResultSet rs = statement.executeQuery();
if (rs.next()) {
int max = rs.getInt(1);
return max + 1;
}
return 1;
} catch (SQLException e) {
throw new HibernateException(e);
}
}
// (...)
}