Еще одна реализация, более простая.
Эта работает с обеими конфигурациями на основе аннотаций или на основе xml: она использует метаданные hibernate для получения значения id для объекта,Замените SequenceGenerator
на IdentityGenerator
(или любой другой генератор) в зависимости от вашей конфигурации.(Создание декоратора вместо создания подкласса с передачей генератора декорированных идентификаторов в качестве параметра этому генератору оставлено читателю в качестве упражнения).
public class UseExistingOrGenerateIdGenerator extends SequenceGenerator {
@Override
public Serializable generate(SessionImplementor session, Object object)
throws HibernateException {
Serializable id = session.getEntityPersister(null, object)
.getClassMetadata().getIdentifier(object, session);
return id != null ? id : super.generate(session, object);
}
}
Ответ на упражнение (используяшаблон декоратора, как и было запрошено), на самом деле не проверено:
public class UseExistingOrGenerateIdGenerator implements IdentifierGenerator, Configurable {
private IdentifierGenerator defaultGenerator;
@Override
public void configure(Type type, Properties params, Dialect d)
throws MappingException;
// For example: take a class name and create an instance
this.defaultGenerator = buildGeneratorFromParams(
params.getProperty("default"));
}
@Override
public Serializable generate(SessionImplementor session, Object object)
throws HibernateException {
Serializable id = session.getEntityPersister(null, object)
.getClassMetadata().getIdentifier(object, session);
return id != null ? id : defaultGenerator.generate(session, object);
}
}