#spring-mvc #jpa #oracle11g #spring-data-jpa #multiple-instances
#spring-mvc #jpa #oracle11g #spring-data-jpa #несколько экземпляров
Вопрос:
У меня есть объект jpa, у которого уже есть идентификатор, сгенерированный как uuid, и требуется еще один уникальный читаемый человеком идентификатор. итак, я сгенерировал ref_key с ValueGenerator
помощью .
@Id@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Type(type = "uuid-char")@Column(name="ID")
private UUID id;
@GeneratorType(type = UniqueIdGenerator.class, when = GenerationTime.INSERT)
@Column(name = "REF_KEY", updatable = false, insertable = true, unique = true, nullable = false)
private String refKey;
Для генерации этого уникального ref_key я использовал временную метку и простой счетчик. Код приведен ниже
public class UniqueIdGenerator implements ValueGenerator {
private static volatile String lastTimestamp = "";
private static volatile int counter = 1;
private String valuePrefix = "UNI_";
@Override
public String generateValue(Session session, Object owner) {
return generateUniqueId(valuePrefix);
}
private static synchronized String generateUniqueId(String prefix) {
String id;
Date dNow = new Date();
SimpleDateFormat ft = new SimpleDateFormat("yyMMdd_HHmmss");
String datetimeId = ft.format(dNow);
if (lastTimestamp.equalsIgnoreCase(datetimeId)) {
id = prefix datetimeId "_" counter;
counter ;
} else {
id = prefix datetimeId;
counter = 1;
}
lastTimestamp = datetimeId;
return id;
}
}
Все это отлично работает с одним экземпляром. Но для этого приложения для балансировки нагрузки развертывается несколько экземпляров, поэтому очень высока вероятность того, что один и тот же идентификатор будет сгенерирован и вставлен в БД в один и тот же момент. Как я могу избежать получения дубликатов в БД? Какой может быть лучший подход?
В БД использовался Oracle 11g.
Я попробовал несколько разных вещей, прежде чем перейти к этому подходу, например, используя последовательность из конца базы данных, но это не сработало, и вся часть модели / объекта упаковывается отдельно, я не смог попасть в БД из этой части. Что еще можно сделать, чтобы создать уникальное значение счетчика и вставить его в БД в соответствии с экземплярами. Пожалуйста, помогите.
Комментарии:
1. «Мне не удалось попасть в БД из этой части» — см. Эту статью о том, как «попасть в БД»
2. Спасибо crizzis, я также реализовал все из этой статьи, та же реализация не работала для меня. Этот генератор последовательностей работает с аннотацией @Id. И в моем случае Id уже был доступен. итак, GenericGenrator не сработал.
3. Достаточно справедливо, но
generateValue
дает вам доступ кSession
значению, что вы можете выполнить буквально любой запрос, который вам нравится. Просто используйтеsession.createSQLQuery("SELECT mySequence.NEXTVAL FROM dual")
4. пробовал и это, crizzis, но это не сработало, насколько я помню, я получал исключение SQL с недопустимыми идентификаторами, пытаясь получить список результатов или uniqueResult и т. Д. Пробовал CreateQuery, CreateSQLQuery, createNativeQuery… но ничего не сработало.
5. Ну, если вы получаете «недопустимый идентификатор», это означает, что вы пытаетесь получить доступ к объекту БД, который не существует. НО это также означает, что вам только что удалось получить доступ к БД. Вам просто нужно выдать действительный запрос.