Клониране на дефиниция на таблица с Hibernate (hbm2ddl)

В моето приложение за хибернация има обект, управляван от анотации: AuditEvent. Той е много прост и няма връзки с външен ключ. Архивирам стари записи в тази таблица, като ги премествам в друга таблица OldAuditEvent, която е клонинг на таблицата AuditEvent.

В момента генерираме DDL за цялото приложение с помощта на hbm2ddl (на нашия анотиран модел на данни) и ръчно копираме/поставяме таблицата AuditEvent и променяме името й, за да създадем OldAuditEvent.

Искам да автоматизирам процеса на изграждане, има ли някакъв начин да кажа на hbb2ddl: „хей, вземете този обект, променете името на таблицата на X и регенерирайте това да е DDL“?

Актуализация: Успях да накарам това да работи чрез подхода, който очертахте. Единственият проблем беше да стигнете до AnnotationSessionFactoryBean, тъй като той е фабричен bean и spring ще ви даде само резултата от неговата фабрика. Създадох ConfigExposingAnnotationSessionFactoryBean (разширяващ AnnotationSessionFactoryBean), за да изложа фабриката на bean чрез статичен -- нещо като хак, но всичко, което искам да направя, е да изпълня задача за време за изграждане.

Configuration cfg = ConfigExposingAnnotationSessionFactoryBean.s_instance.getConfiguration();

PersistentClass pClass = cfg.getClassMapping("com.myco.LoginAttempt");
pClass.getTable().setName("ArchiveLoginAttempt");

Dialect dialect = Dialect.getDialect(ConfigExposingAnnotationSessionFactoryBean.s_instance.getHibernateProperties());

// only output create tables, not indexes or FK
for (String s : cfg.generateSchemaCreationScript( dialect )) {
    if (s.contains("create table") && s.contains("Archive")) {
        m_outstream.print(s);
        m_outstream.println(";");
    }
}

person Justin    schedule 06.08.2009    source източник


Отговори (1)


Това е изпълнимо, но доста разхвърляно и най-вероятно не си струва в този случай.

Ще трябва да промените динамично Конфигурация обект преди SessionFactory да бъде изграден. Ако използвате Spring, това може да стане чрез замяна на метода postProcessAnnotationConfiguration() на AnnotationSessionFactoryBean; в противен случай просто ще трябва да го направите, като използвате вашия Configuration обект, преди да извикате buildSessionFactory() върху него.

Можете да получите достъп до съпоставяния на клас/таблица чрез configuration.getMappings(). След това ще трябва да намерите картографирането на вашата таблица чрез getTable(), да създадете копие с ново име чрез addTable() и да копирате всички колони/ключове чрез API на таблици.

След това можете да генерирате DDL скрипта чрез generateSchemaCreationScript() или generateSchemaUpdateScript() методи на Configuration обект.

Както казах, вероятно не си струва в този случай :-)

person ChssPly76    schedule 06.08.2009
comment
Ще опитам това и ще видя дали работи! Дори за 2 маси мисля, че си заслужава - ръчните стъпки в процеса на изграждане на различни платформи просто влачат нещата надолу и причиняват неочаквани проблеми. - person Justin; 07.08.2009
comment
Успех с внедряването. Горният подход работи за мен, въпреки че го използвам за различна цел (манипулиране на картографиране на обекти по време на изпълнение). Трябва да кажа обаче, че съм доста раздразнен от пренареждането на колони на Hibernate в DDL скрипта - искам да поддържам същия ред като в анотациите на изходния код. Решихте ли това по някакъв начин или това не е проблем за вас? - person ChssPly76; 07.08.2009
comment
Нашият процес на разработка е: анотиран POJO -› DDL. Винаги минаваме през имена на свойства в хибернация, така че не ни интересуват позициите на колоните. Ако hibernate пренарежда произволно, това означава, че вероятно използва HashSet/Map някъде вътрешно. Намерете кода, превключете го към TreeSet/Map и може да получите последователно подреждане? - person Justin; 07.08.2009
comment
* това ще ви даде сортиран и последователен ред, но не и това, което искате. Трябва да приложите сортиране в крайния процес, който сканира анотациите и пренарежда вътрешната структура на хибернация въз основа на анотацията на класа. - person Justin; 07.08.2009
comment
Да, правя това за обикновените атрибути и това е огромна болка :-) Почти невъзможно е обаче да се направи това за асоциации (без да се пренаписва значителна част от обектите с метаданни на Hibernate), така че те винаги остават последни в таблицата. Примирих се с това :-), но когато видях, че генерирате DDL от POJO анотации, реших, че ще проверя дали сте се сблъсквали и може би сте разрешили този проблем. - person ChssPly76; 07.08.2009