В рамках обновления hibernate я не могу настроить фабрику сеансов.Во время выполнения, в зависимости от системной переменной, мы используем схему или mock_schema.Мы делали настройку в postProcessConfiguration.
Я не очень ясно, где подключить код и не очень ясно, о весеннем потоке при генерации фабрики сессий.
Из спящего режима у меня есть решение.https://vladmihalcea.com/how-to-get-the-entity-mapping-to-database-table-binding-metadata-from-hibernate/#comments
- Как сделать так, чтобы несколько интеграторов сказали
MetadataExtractorIntegrator
и EventListenerIntegrator
. - Как настроить incase из
CustomLocalSessionFactoryBean
(extends LocalSessionFactoryBean
). - Можно ли это сделать без переопределения
LocalSessionFactoryBean
? Как получить / изменить getCollectionMappings
из конфигурации?
открытый класс CustomHibernateSessionFactoryBean расширяет org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean {
@Inject
private DatabasePlatform dbPlatform;
@Inject
private ApplicationContext applicationContext;
@Override
protected SessionFactory newSessionFactory(Configuration config) {
config.setProperty(DatabasePlatform.HIBERNATE_DIALECT_KEY, this.dbPlatform.getDialectClass().getName());
//Many such event listeners
config.getEventListeners().setUpdateEventListeners(sortAndConcat(config.getEventListeners().getUpdateEventListeners(),saveOrUpdateEventListeners));
return super.newSessionFactory(config);
}
@Override
protected void postProcessConfiguration(Configuration config) {
super.postProcessConfiguration(config);
if (!DatabasePlatform.INVENTORY_SCHEMA.equals(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA)) {
logger.info("Overriding inventory schema name to %s", DatabasePlatform.INVENTORY_SCHEMA);
Iterator<PersistentClass> classIterator = config.getClassMappings();
while (classIterator.hasNext()) {
PersistentClass persistentClass = classIterator.next();
replaceSchemaName(persistentClass.getTable());
Iterator<Join> joinIterator = persistentClass.getJoinIterator();
while (joinIterator.hasNext()) {
replaceSchemaName(joinIterator.next().getTable());
}
Iterator<org.hibernate.mapping.Collection> collectionIterator = config.getCollectionMappings();
while (collectionIterator.hasNext()) {
replaceSchemaName(collectionIterator.next().getCollectionTable());
}
}
}
}
private void replaceSchemaName(Table table) {
if (DatabasePlatform.DEFAULT_INVENTORY_SCHEMA.equals(table.getSchema())) {
table.setSchema(DatabasePlatform.INVENTORY_SCHEMA);
}
if (table.getName().startsWith(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA + ".")) {
table.setName(table.getName().replaceFirst(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA, DatabasePlatform.INVENTORY_SCHEMA));
}
}
}
Новый код, который я пытаюсь использовать в спящем режиме 5
@SuppressWarnings("unused")
public class CustomHibernateSessionFactoryBean extends org.springframework.orm.hibernate5.LocalSessionFactoryBean {
@Inject
private ApplicationContext applicationContext;
private static final SystemLogger logger = SystemLogger.getLogger(CustomHibernateSessionFactoryBean.class);
@Inject
private DatabasePlatform dbPlatform;
private AsyncTaskExecutor bootstrapExecutor;
private EventListenerIntegrator eventListenerIntegrator;
private final RegionFactory regionFactory;
private boolean metadataSourcesAccessed;
private MetadataSources metadataSources;
public CustomHibernateSessionFactoryBean() {
// TODO: Check what is the effect of regionFactory not being set
regionFactory = null;
}
CustomHibernateSessionFactoryBean(RegionFactory regionFactory, EventListenerIntegrator eventListenerIntegrator) {
this.regionFactory = regionFactory;
this.eventListenerIntegrator = eventListenerIntegrator;
}
CustomHibernateSessionFactoryBean(EventListenerIntegrator eventListenerIntegrator) {
this.regionFactory = null;
this.eventListenerIntegrator = eventListenerIntegrator;
}
@Override
public void setMetadataSources(MetadataSources metadataSources) {
Assert.notNull(metadataSources, "MetadataSources must not be null");
this.metadataSourcesAccessed = true;
this.metadataSources = metadataSources;
}
@Override
public MetadataSources getMetadataSources() {
this.metadataSourcesAccessed = true;
if (this.metadataSources == null) {
BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
ResourcePatternResolver resourcePatternResolver = (ResourcePatternResolver) getResourceLoader();
if (resourcePatternResolver != null) {
builder = builder.applyClassLoader(resourcePatternResolver.getClassLoader()).applyIntegrator(eventListenerIntegrator);
}
this.metadataSources = new MetadataSources(builder.build());
}
return this.metadataSources;
}
@Override
protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) {
getConfiguration().setProperty(DatabasePlatform.HIBERNATE_DIALECT_KEY, this.dbPlatform.getDialectClass().getName());
if (!DatabasePlatform.INVENTORY_SCHEMA.equals(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA)) {
logger.info("Overriding inventory schema name to %s", DatabasePlatform.INVENTORY_SCHEMA);
Metadata metadata = getMetadataSources().getMetadataBuilder().build();
Collection<PersistentClass> entityBindings = metadata.getEntityBindings();
for (Iterator<PersistentClass> iterator = entityBindings.iterator(); iterator.hasNext();) {
PersistentClass persistentClass = iterator.next();
replaceSchemaName(persistentClass.getTable());
@SuppressWarnings("unchecked")
Iterator<Join> joinIterator = persistentClass.getJoinIterator();
while (joinIterator.hasNext()) {
replaceSchemaName(joinIterator.next().getTable());
}
}
}
return (this.bootstrapExecutor != null ? sfb.buildSessionFactory(this.bootstrapExecutor) : sfb.buildSessionFactory());
}
private void replaceSchemaName(Table table) {
if (DatabasePlatform.DEFAULT_INVENTORY_SCHEMA.equals(table.getSchema())) {
table.setSchema(DatabasePlatform.INVENTORY_SCHEMA);
}
if (table.getName().startsWith(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA + ".")) {
table.setName(table.getName().replaceFirst(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA, DatabasePlatform.INVENTORY_SCHEMA));
}
}
}
Почемумне нужно настроить localsessionFactoryBean?
I have 2 need for using SessionFactoryBean
1. Normal application
2. Dbtest
In normal application, schema1 is populated by other process
In Dbtest, i need to use mock_schema1 instead of schema1 so that we will not rewrite data populated by other application.
@ Table(name = “cluster”, schema = “schema1”)
@ SecondaryTable(name = “Cluster”, schema = “schema2”, pkJoinColumns = @ PrimaryKeyJoinColumn(name = “clusterId”, referencedColumnName = “objid”))
@ org.hibernate.annotations.Table(appliesTo = “Cluster”, optional = false)
@ Entity
@ OptimisticLocking(type = OptimisticLockType.DIRTY)
@ DynamicUpdate
public class Cluster implements Serializable {
} Но если вы видите, что мое определение сущности использует "schema1" во время выполнения, если я запускаю Dbtest, я хочу, чтобы сущность использовала "mock_schema1" вместо "schema1"
======================================================================== Это ответ на M.Вопрос Deinum :
В моем тесте настройка hibernate.default_schema не будет служить моей цели.
Пример.как часть dbtest, если я установлю кластерный объект и сохраню его, он попытается заполнить mock_schema2 и schema1.Вместо этого я хочу schema2 и mock_schema1.