Я постараюсь сказать это просто. У меня есть таблица с составным первичным ключом, состоящим из двух атрибутов Long, обернутых аннотированным классом @IdClass.
Атрибуты @IdClass:
public class MyPK implements Serializable {
private Long id;
private Long version;
} // + hashCode, constructors, etc.
Что я не могу сделать:
Чтобы ВСТАВИТЬ новую запись, сохраняя значение «id» и увеличивая «версию».
Пример сценария:
Существующая запись — {id:1, версия:1}
Желаемая новая запись (НЕ ОБНОВЛЕНА, речь о новой) - {id:1, version:2}
Что я сделал:
Сначала я попытался увеличить версию, сохранив генератор последовательностей, который использовал. Ниже показано, как был аннотирован идентификатор:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idSequence")
@SequenceGenerator(name = "idSequence", sequenceName = "SQ_ID", allocationSize = 1)
@Column(name = "ID", nullable = false, updatable = false)
private Long id;
Вышеприведенное привело к тому, что предоставленный идентификатор был переопределен с помощью nextVal последовательности, поэтому для меня это не проблема.
Итак, мой второй подход заключался в том, чтобы поиграть с наследованием и внутренними классами Hibernate, чего я всегда стараюсь избегать:
public class MySequenceStyleIdGenerator extends SequenceStyleGenerator {
@Override
public Serializable generate(SessionImplementor session, Object object){
Serializable id = session.getEntityPersister(null, object)
.getClassMetadata().getIdentifier(object, session);
return id != null && ((MyPK)id).getId() != null
? id : super.generate(session, object);
}
}
И внесение изменений в класс сущности по мере необходимости:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "providedIdOrSequence")
@GenericGenerator(
name="providedIdOrSequence",
strategy="{package}.MySequenceStyleIdGenerator",
parameters = @org.hibernate.annotations.Parameter(
name = "sequence_name",
value = "SQ_ID"
)
)
@Column(name = "ID", nullable = false, updatable = false)
private Long id;
Это, с другой стороны, возвращает nextVal в id ТОЛЬКО, когда он равен нулю, чего я и хотел. Затем проблема переходит к чему-то более темному и глубокому в библиотеке, как будто она пытается присвоить идентификатор (Long) самому типу PK вместо его атрибута Long:
java.lang.IllegalArgumentException: невозможно установить для поля java.lang.Long {package}.CotacaoPK.idCotacao значение {package}.CotacaoPK
Если оба атрибута PK (идентификатор и версия) остаются неизменными, я не получаю ошибки.
Любые идеи? Я уже потратил на это разумное количество часов... спасибо.