Смешивание автоинкремента и ручных значений - не очень хорошая идея. Как должна вести себя ваша база данных, когда ваша текущая последовательность указывает на 11, но вы вставляете запись со значением 20? Как только последовательность достигнет 20, вы получите уникальное нарушение ограничений. Чтобы предотвратить это, вам нужно будет убедиться, что генерируемое значение последовательности не противоречит какой-либо существующей записи, - которая собирается ввести целую кучу других проблем с повторением, блокировкой и т. Д.
Это может быть хорошей идеей переосмыслить свою модель или требования, почему вы второй псевдо Id? И почему это можно заполнить как вручную, так и автоматически? , если вы настаиваете на этой функции, вы можете заставить ее работать, если вы гарантируете, что записи вручную не сталкиваются с автогенерированными. Затем вы можете создать собственный генератор идентификаторов для своего столбца «истинный идентификатор» (Integer id) и переопределить метод generate
, так что помимо генерации идентификатора вы также проверяете значение вашего псевдонима «(идентификатор маршрута)» (routeNumberId). Если это null
, вы можете попросить БД дать вам следующее значение из некоторой последовательности. Фиктивная ниже реализация:
@Override
public synchronized Serializable generate(SessionImplementor session, Object object) throws HibernateException {
Serializable result;
if (object instanceof Route) {
Route reoute= ((Route) object);
if (route.getid() != null) {
result = (Serializable) route.getId();
} else {
result = <GENERATE new ID(e.g. call super, etc)> ;
}
if (route.getRouteNumberId() == null) {
long autoIncrRouteId = <GENERATE new routeID,>
route.setRouteNumberId(autoIncrRouteId);
}
return result;
} else {
result = super.generate(session, object);
}
return result;
}
Другой вариант заключается в использовании @PrePersist сущности слушателя и сделать чек и/или последовательность вызова там. Однако было бы сложно получить доступ к диспетчеру сущностей или контексту JPA от слушателей, так как большинство поставщиков JPA не полностью поддерживают инъекцию в слушатели сущностей. Вы можете выполнить ручной поиск jndi, но сначала переосмыслите то, что вы пытаетесь достичь, если это того стоит.
Редактировать: функциональный код генератора кода (postgres).
@Override
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
Connection connection = session.connection();
try {
Route route= ((Route) obj);
String seqName = "you_db_id_sequence";
PreparedStatement ps = connection.prepareStatement("SELECT nextval ('" + seqName + "') as nextval");
ResultSet rs = ps.executeQuery();
if (rs.next()) {
int id = rs.getInt("nextval");
log.info("Generated order id {} ", id);
if (route.getRouteNumberId() == null) {
route.setrouteNumberid(id); //or call another sequence to get a different id
}
return Long.parseLong(code);
} else {
throw new IllegalStateException("could not generate new id");
}
} catch (SQLException e) {
log.error("Could not generate id!", e);
throw new HibernateException("Unable to generate id from Sequence");
}
return null;
}
Вы пытались что-то кодировать? – msagala25
Добро пожаловать в StackOverflow. Вы должны опубликовать код, чтобы показать свои усилия в отношении того, чего вы пытаетесь достичь. Это также поможет другим пользователям ответить на ваш вопрос. –
Я обновил его. @SouravGhosh –