在ConstraintViolationException上重试@GenericGenerator

时间:2019-04-16 11:50:01

标签: hibernate spring-data

我正在使用@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);
        }
    }

    // (...)
}

0 个答案:

没有答案