2

I'm using LocalContainerEntityManagerFactoryBean and using the packages to scan option.

I would like to to have a simple utility that I can run which will print out the ddl changes that it thinks I should run. Which I will then review and craft my liquibase changesets from.

Douglas Ferguson
  • 1,242
  • 2
  • 14
  • 25

3 Answers3

0

Here's my solution using Spring 4 and Hibernate 4. It doesn't respect some of the annotations on update like @ForeignKey, but it does on the export. There are a bunch of flags, and more classes, so there might be a better way still. I would love to do more of a workflow from this point. Perhaps some kind of workflow with git so you can track the changes and compare against your liquibase file?

public static void main(String[] args) throws IOException {

    ApplicationContext context = new AnnotationConfigApplicationContext(DataConfig.class, PropertySourceConfig.class);
    EntityManager entityManager = context.getBean(EntityManager.class);

    DataConfig dataConfig = context.getBean(DataConfig.class);

    String dialect = "org.hibernate.dialect.PostgreSQL9Dialect";

    Configuration cfg = new Configuration();
    cfg.setProperty("hibernate.hbm2ddl.auto", "update");
    cfg.setProperty("hibernate.dialect", dialect);
    cfg.setProperty("hibernate.connection.url", dataConfig.getUserNamePasswordConnectionUrl());

    for (EntityType<?> entity : entityManager.getMetamodel().getEntities()) {
        cfg.addAnnotatedClass(entity.getJavaType());
    }



    SchemaExport export = new SchemaExport(cfg);
    export.setDelimiter(";");
    File tempExportFile = File.createTempFile("Export", null);

    export.setOutputFile(tempExportFile.getAbsolutePath());
    export.setFormat(true);
    export.execute(true, false, false, false);

    System.out.println("EXPORT SCRIPT = " + FileUtils.readFileToString(tempExportFile));

    File tempUpdateFile = File.createTempFile("Update", null);

    SchemaUpdate update = new SchemaUpdate(cfg);
    update.setDelimiter(";");
    update.setOutputFile(tempUpdateFile.getAbsolutePath());
    update.setFormat(true);
    update.execute(true,false);

    System.out.println("UPDATE SCRIPT = " + FileUtils.readFileToString(tempUpdateFile));


}
Matt Broekhuis
  • 1,985
  • 2
  • 26
  • 35
0

Why not use liquibase's diff functionality to generate the changesets?

comparing databases and genrating sql script using liquibase

Community
  • 1
  • 1
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • That's not the scenario I'm dealing with. In my case, the desired schema doesn't exist in any database.I want to be able to add a pojo, then run a command have it tell me what it thinks the schema should be, then I will take that into consideration when building the liquibase xml. This will help me to double check my work. – Douglas Ferguson Mar 04 '12 at 16:58
0

Liquibase has some support for comparing a hibernate configuration with an existing database, but it does not currently support scanned packages. See http://www.liquibase.org/manual/hibernate for some information on the hibernate support, and https://github.com/liquibase/liquibase-hibernate for the source.

Depending on the level of effort you want to put in, it would not be overly difficulty to use the existing liquibase-hiberante source as a base for your utility. The basic idea is to get a hibernate Configuration object and make a liquibase.Database wrapper for it. The existing code builds up the hibernate Configuration object from a hibernate config xml file, but you can get your Configuration from your LocalContainerEntityManagerFactoryBean directly.

Nathan Voxland
  • 15,453
  • 2
  • 48
  • 64
  • https://github.com/RichardBradley/liquibase.github.com/commit/d1ac4950df280a140768a8c1421c221203d3c63d has some information on extracting and using a Configuration object – Nathan Voxland Mar 06 '12 at 20:23
  • I still don't see how I can get the Configuration from LocalContainerEntityManager. The closest thing I've found is this: org.hibernate.ejb.Ejb3Configuration cfg = new org.hibernate.ejb.Ejb3Configuration(); org.hibernate.ejb.Ejb3Configuration configured = cfg.configure(fb.getPersistenceUnitInfo(), fb.getJpaPropertyMap()); org.hibernate.tool.hbm2ddl.SchemaExport schemaExport = new org.hibernate.tool.hbm2ddl.SchemaExport(configured.getHibernateConfiguration()); But it has lots of deprecated calls. – Douglas Ferguson Mar 09 '12 at 06:57
  • I got this working, but this isn't really want I was looking for. This just spits out the changeset that you'd want to run against an empty database. I want to know the changeset required to update my local db to have what hibernate expects. – Douglas Ferguson Mar 09 '12 at 07:44
  • It looks like LocalContainerEntityManager has different interfaces it exposes than the Hibernate-native configuration. A JPA version of the HibernateDatabase may need to be implemented and be completely separate – Nathan Voxland Mar 09 '12 at 21:01