我正在使用@GenericGenerator
处理复合主键的创建。在并发调用的情况下,有时会失败并显示ConstraintViolationException
。我宁愿设置一个重试机制,而不是使一些并发的POST调用失败。问题是我无法强制对密钥进行重新生成。
我曾尝试在失败时再次使用相同的对象调用JpaRepository#saveAndFlush
,但是@Id
保持不变。
是否有一种通用的方法来在@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);
}
}
// (...)
}