我已经按照基本的弗拉德指南来实现前缀发生器,但是遇到了问题。
目标是同时:
@GenericGenerator
)hibernate.hbm2ddl.auto=create
在每个应用重启(重新部署,无论......)时删除并创建所有序列。如何同时实施这些条件?
我设法用这个部分解决了这个任务:
@GenericGenerator(
name = "prefix-sequence",
strategy = "soberich.utils.StringSequenceIdentifier",
parameters = {
@Parameter(name="prefer_sequence_per_entity", value="true"),
@Parameter(name = SEQUENCE_PREFIX, value = "A-")})
每个class / id-field 上的
和下面的代码片段实现了生成器策略。
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.Session;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import javax.persistence.PersistenceException;
import java.io.Serializable;
import java.util.Properties;
import static java.lang.String.format;
import static java.lang.String.join;
import static org.hibernate.id.enhanced.SequenceStyleGenerator.*;
import static org.hibernate.internal.util.config.ConfigurationHelper.*;
public class StringSequenceIdentifier implements IdentifierGenerator, Configurable {
public static final String SEQUENCE_PREFIX = "sequence_prefix";
private String sequencePrefix;
private String sequenceCallSyntax;
@Override
public void configure(final Type type,
final Properties params,
final ServiceRegistry serviceRegistry) throws MappingException {
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(JdbcEnvironment.class);
final Dialect dialect = jdbcEnvironment.getDialect();
sequencePrefix = getString(SEQUENCE_PREFIX, params, "SEQ_");
final String sequencePerEntitySuffix =
getString(CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, params, DEF_SEQUENCE_SUFFIX);
final String defaultSequenceName =
getBoolean(CONFIG_PREFER_SEQUENCE_PER_ENTITY, params, false)
? params.getProperty(JPA_ENTITY_NAME) + sequencePerEntitySuffix
: DEF_SEQUENCE_NAME;
sequenceCallSyntax =
dialect.getSequenceNextValString(getString(SEQUENCE_PARAM, params, defaultSequenceName));
}
@Override
public Serializable generate(final SharedSessionContractImplementor session,
final Object object) throws HibernateException {
final long seqValue = ((Number) Session.class.cast(session)
.createNativeQuery(sequenceCallSyntax)
.uniqueResult()).longValue();
return sequencePrefix + format("%011d", seqValue);
}
}
" Entity_SEQ" - 自动生成
并在重启后丢弃它们,但是
entity_seq - 小写序列是用于nextval('entity_seq')
的真实序列。因此,您应该在重新启动期间手动创建它们,而drop
阶段异常将像"..relation "entity_seq" does not exist"
一样抛出。所以,基本上它不能自动工作。你必须创建序列!
感觉应该有一个非常简单的解决方案。
"prefix-sequence"
的序列,该序列是@GenericGenerator
上的名称。如果相反@Parameter(name="prefer_sequence_per_entity", value="true")
我将@Parameter(name = "sequence_name", value = "entity_seq")
放在class / id-field上,我不明白为什么会发生完全相同的事。