Clone a Table's definition with Hibernate (hbm

2019-02-15 19:18发布

问题:

In my hibernate application there is annotation driven object: AuditEvent. Its very simple and has no foreign key relationships. I archive old entries in this table by moving them to another table OldAuditEvent, which is a clone of the AuditEvent table.

Right now we generate the DDL for the entire application using hbm2ddl (on our annotated datamodel) and manually copy/paste the AuditEvent table and change its name to create OldAuditEvent.

I want to automate the build process, is there any way to tell hbb2ddl: "hey take this entity, change the table name to X and regenerate it's DDL"?

Update: I was able to get this working by the approach you outlined. The only trouble was getting at the AnnotationSessionFactoryBean since it is a factory bean and spring will only give you the output of its factory. I created ConfigExposingAnnotationSessionFactoryBean (extending AnnotationSessionFactoryBean) to expose the bean factory through a static -- sort of a hack but all I want to do is run a build time task.

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(";");
    }
}

回答1:

It's doable but rather messy and, most likely, not worth it in this case.

You'll need to dynamically alter Hibernate's Configuration object before SessionFactory is built. I you're using Spring, this can be done by overriding postProcessAnnotationConfiguration() method of AnnotationSessionFactoryBean; otherwise you'll just need to do it using your Configuration object prior to invoking buildSessionFactory() on it.

You can get access to class / table mappings via configuration.getMappings(). You will then need to find your table mapping via getTable(), create a copy with new name via addTable() and replicate all columns / keys via Table API.

You can then generate the DDL script via generateSchemaCreationScript() or generateSchemaUpdateScript() methods of Configuration object.

As I said, probably not worth it in this case :-)