#hibernate #sequence
#гибернация #последовательность
Вопрос:
Привет, у меня есть доменный объект, допустим, Student и его откат no в качестве первичного ключа
вот пример сопоставления для него.
@Id
@Column(name = "Roll_NO", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Roll_NO_SEQ")
@SequenceGenerator(name = "Roll_NO_SEQ", sequenceName = "Roll_NO_SEQ", allocationSize = 1)
public Long getRollNo() {
return this.rollNo;
}
проблема: допустим, если конкретный учащийся был удален из базы данных, а затем повторно принят во время повторного приема, я хочу сохранить старый номер броска. поэтому, когда я вызываю session.save hibernate, присваивает новый номер отката на основе указанной последовательности, а не того, что я устанавливаю с помощью метода setRollNo(). есть ли какой-либо способ добиться этого в режиме гибернации?
Ответ №1:
не удаляйте запись, добавьте новое логическое поле с именем soemthign, например, active или valid, и вместо удаления просто сделайте active = false .
Или,
Вы можете вставить запись, подлежащую удалению, в таблицу архива, а затем удалить, а затем посмотреть оттуда.
Комментарии:
1. я не могу изменить существующую функциональность. поскольку это устаревший код
Ответ №2:
Учитывая, что вы не можете изменить устаревший код, у Райана правильная идея. Некоторое время назад мне пришлось сделать в основном то же самое в личном проекте. Было две части: простая часть — разрешить эффективную настройку идентификатора столбца с автоматической нумерацией в противном случае … а другая — заставить генератор идентификаторов перестать перезаписывать это значение при переходе к Save() .
Вот код для FlexibleIDGenerator, который я использовал:
public class FlexibleIDGenerator extends IdentityGenerator implements Configurable {
public static final String DEFAULT = "default";
private IdentifierGenerator assignedGenerator;
private IdentifierGenerator defaultGenerator;
@SuppressWarnings("unchecked")
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
//boolean useDefault = false;
if (object instanceof OverridableIdentity) {
if (((OverridableIdentity) object).isIDOverridden()) {
try {
Class cl = object.getClass().getSuperclass();
Method[] methods = cl.getDeclaredMethods();
for (int i = 0; i < methods.length; i ) {
if (methods[i].getName().equalsIgnoreCase("setId")) {
methods[i].invoke(object, Integer.valueOf((((OverridableIdentity) object).getOverriddenID())));
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return assignedGenerator.generate(session, object);
} else {
return defaultGenerator.generate(session, object);
}
} else {
return defaultGenerator.generate(session, object);
}
}
public void configure(Type type, Properties params, Dialect d) throws MappingException {
assignedGenerator = IdentifierGeneratorFactory.create("assigned", type, params, d);
defaultGenerator = IdentifierGeneratorFactory.create("increment", type, params, d);
}
}
Чтобы использовать это для класса, вы обновляете файл отображения гибернации следующим образом:
<id
name="Id"
type="integer"
column="id"
>
<generator class="com.mypackage.FlexibleIDGenerator"/>
</id>
Еще одна деталь: я добавил метод к своему базовому объекту с именем «GetOverriddenID ()», чтобы избежать путаницы в том, использую ли я «обычный» идентификатор (в вызовах Update ()) или переопределенные.
Надеюсь, это поможет.
Ответ №3:
Учитывая, что вы не можете изменить удаление строк, другим способом было бы написать свой собственный генератор идентификаторов, который получит новое значение последовательности, только если значение еще не присвоено. Информацию о написании собственного генератора см. В конце раздела 5.1.2.2 в справочном руководстве. Я никогда не пробовал этого раньше, поэтому я могу только указать вам общее направление.