Спящий режим 6.5. гибридное создание идентификаторов с помощью @IdGeneratorTypeJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Спящий режим 6.5. гибридное создание идентификаторов с помощью @IdGeneratorType

Сообщение Anonymous »

Моя цель — реализовать собственный генератор идентификаторов, который будет решать во время выполнения (на основе используемого диалекта базы данных), должен ли он генерировать идентификаторы, используя столбец идентификаторов или последовательность, которая уже присутствует в базе данных. Для создания пользовательских генераторов руководство пользователя Hibernate предлагает использовать метааннотацию @IdGeneratorType. Существует пример, в котором эта метааннотация используется вместе с пользовательской реализацией интерфейса IdentifierGenerator. Однако, когда я изучаю реализацию IdentifierGenerator, я нахожу следующий комментарий (см. в javadoc):
"Экземпляры IdentifierGenerator обычно создаются и настраиваются службой IdentifierGeneratorFactory. . Обычно неправильно использовать IdentifierGenerator с метааннотацией IdGeneratorType."
Поэтому я считаю, что руководство пользователя hibernate немного вводит в заблуждение. В javadocs я обнаружил, что @IdGeneratorType нужен класс, реализующий интерфейс Generator. Я хочу, чтобы мой собственный генератор реализовывал как OnExecutionGenerator, так и BeforeExecutionGenerator и во время выполнения (при запуске приложения) решал, какая из двух стратегий будет использоваться. Возможно ли это с помощью @IdGeneratorType? Есть ли какие-то примеры/уточнения, которые мне не хватает? (Мне известен интерфейс GenericGenerator, который позволял это, но он устарел с версии 6.5)
У меня есть класс, реализующий как OnExecutionGenerator, так и BeforeExecutionGenerator

Код: Выделить всё

public class BeforeOrOnExecutionGenerator implements BeforeExecutionGenerator, OnExecutionGenerator {
private final BeforeExecutionGenerator beforeExecutionGenerator;
private final OnExecutionGenerator onExecutionGenerator;
private final boolean generateOnExecution;

public BeforeOrOnExecutionGenerator(BeforeExecutionGenerator beforeExecutionGenerator, OnExecutionGenerator onExecutionGenerator, Dialect dialect) {
this.beforeExecutionGenerator = beforeExecutionGenerator;
this.onExecutionGenerator = onExecutionGenerator;
// decide here based on dialect, if id generation should be using a sequence or identity
this.generateOnExecution = dialect instanceof MySQLDialect || ...
logger.info("using dialect: " + dialect);
}

@Override
public boolean generatedOnExecution() {
return this.generateOnExecution;
}

@Override
public boolean generatedOnExecution(Object entity, SharedSessionContractImplementor session) {
return this.generateOnExecution;
}

@Override
public Object generate(SharedSessionContractImplementor session, Object entity, Object currentValue, EventType eventType) {
return beforeExecutionGenerator.generate(session, entity, currentValue, eventType);
}

@Override
public boolean referenceColumnsInSql(Dialect dialect) {
return onExecutionGenerator.referenceColumnsInSql(dialect);
}

@Override
public boolean writePropertyValue() {
return onExecutionGenerator.writePropertyValue();
}

@Override
public String[] getReferencedColumnValues(Dialect dialect) {
return onExecutionGenerator.getReferencedColumnValues(dialect);
}

@Override
public String[] getUniqueKeyPropertyNames(EntityPersister persister) {
return onExecutionGenerator.getUniqueKeyPropertyNames(persister);
}

@Override
public EnumSet getEventTypes() {
return EventTypeSets.INSERT_ONLY;
}

@Override
public InsertGeneratedIdentifierDelegate getGeneratedIdentifierDelegate(PostInsertIdentityPersister persister) {
return onExecutionGenerator.getGeneratedIdentifierDelegate(persister);
}

@Override
public boolean allowAssignedIdentifiers() {
return getCurrentGenerator().allowAssignedIdentifiers();
}

@Override
public boolean generatesSometimes() {
return getCurrentGenerator().generatesSometimes();
}

@Override
public boolean generatesOnInsert() {
return getCurrentGenerator().generatesOnInsert();
}

@Override
public boolean generatesOnUpdate() {
return getCurrentGenerator().generatesOnUpdate();
}

private Generator getCurrentGenerator() {
if (generateOnExecution) {
return onExecutionGenerator;
}
return beforeExecutionGenerator;
}
}
Затем я реализую собственный генератор следующим образом:

Код: Выделить всё

public class CustomIdGeneratorImpl extends BeforeOrOnExecutionGenerator {

public CustomIdGeneratorImpl(CustomIdGenerator config, Member annotatedMember, CustomIdGeneratorCreationContext context) {
super(new SequenceStyleGenerator(), new IdentityGenerator(), context.getDatabase().getDialect());
}

}
Наконец, я использую мета-аннотацию @IdGeneratorType, чтобы создать свою собственную аннотацию, которую я использую для аннотации столбца Id:

Код: Выделить всё

@Retention(RUNTIME)
@Target({METHOD, FIELD})
@IdGeneratorType(CustomIdGeneratorImpl.class)
public @interface CustomIdGenerator{}
Похоже, это не работает, и все равно пытается вставить строки со столбцами с нулевым идентификатором

Подробнее здесь: https://stackoverflow.com/questions/790 ... eratortype
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»