2014-01-14 57 views
1

我正在使用SchemaExporter生成ddl腳本。使用Hibernate模式導出器生成模式失敗,因爲@ManyToOne關係

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

     SchemaDDLGenerator.execute(Dialect.ORACLE, Key.class); 
} 

Key類:

@Entity 

public class Key extends AbstractEntity { 

private static final long serialVersionUID = 7467094398251027638L; 

@Id 
@GeneratedValue(strategy = GenerationType.SEQUENCE) 
@Column(name = "KEY_SID") 
private Long id; 
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER) 
private API granter; 
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER) 
private API grantee; 

API實體類是簡單的列的實體類。

模式生成:

public class SchemaDDLGenerator { 

public static void execute(Dialect dialect, Class<?>... classes) { 
    Configuration configuration = new Configuration(); 
    configuration.setProperty(Environment.DIALECT, dialect.getClassName()); 
    for (Class<?> entityClass : classes) { 
     configuration.addAnnotatedClass(entityClass); 
    } 
    SchemaExport schemaExport = new SchemaExport(configuration); 
    schemaExport.setDelimiter(";"); 
    boolean consolePrint = true; 
    boolean exportInDatabase = false; 
    schemaExport.setOutputFile(String.format("ddl_%s_drop.%s ", new Object[] { dialect.name().toLowerCase(), "sql" })); 
    schemaExport.drop(false, false); 
    schemaExport.setOutputFile(String.format("ddl_%s.%s ", new Object[] { dialect.name().toLowerCase(), "sql" })); 
    schemaExport.create(consolePrint, exportInDatabase); 
} 

}

它工作正常進行,不具有任何關係的實體,但它拋出錯誤有@OneToMany或@ManyToOne關係的人。

Exception in thread "main" org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.example.data.model.ClientRelationship.grantee references an unknown entity: com.example.data.model.Client 
at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:109) 
at org.hibernate.cfg.Configuration.processEndOfQueue(Configuration.java:1532) 
at org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:1453) 
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1358) 
at org.hibernate.cfg.Configuration.generateDropSchemaScript(Configuration.java:934) 
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:188) 
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:156) 
at com.example.util.db.SchemaDDLGenerator.execute(SchemaDDLGenerator.java:16) 
at com.example.data.generator.SchemaGenerator.main(SchemaGenerator.java:67) 

以下是基於Java的Hibernate配置

@Configuration 
@Import({ DataConfigDefault.class, DataConfigCi.class }) 
@ComponentScan(basePackages = "com.example.data.repository.util") 
@EnableJpaRepositories(basePackages = { "com.example.data.repository" }) 
@EnableTransactionManagement(mode = AdviceMode.PROXY) 
public class DataConfig { 

private static Logger logger = LoggerFactory.getLogger(DataConfig.class); 

@Autowired 
private Environment environment; 

@PostConstruct 
public void postConstruct() { 
    logger.debug("active profiles: ({})", StringUtils.join(environment.getActiveProfiles(), ",")); 
} 

static DataSource createH2Datasource(String jdbcUrl) { 
    logger.debug("creating h2 data source using: {}", jdbcUrl); 
    JdbcDataSource ds = new JdbcDataSource(); 
    ds.setURL(jdbcUrl); 
    ds.setUser("sa"); 
    ds.setPassword(""); 
    return ds; 
} 

@Value("classpath:seed-data.sql") 
private Resource h2Schema; 

@Value("classpath:test-data.sql") 
private Resource h2DataScript; 

@Autowired 
@Bean 
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) { 

    final DataSourceInitializer initializer = new DataSourceInitializer(); 
    initializer.setDataSource(dataSource); 
    initializer.setDatabasePopulator(databasePopulator()); 
    return initializer; 
} 

private DatabasePopulator databasePopulator() { 
    final ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); 
    populator.addScript(h2Schema); 
    populator.addScript(h2DataScript); 
    return populator; 
} 

@Bean 
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { 
    JpaTransactionManager transactionManager = new JpaTransactionManager(); 
    transactionManager.setEntityManagerFactory(entityManagerFactory); 
    return transactionManager; 
} 

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactory(Environment env, DataSource dataSource) { 
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
    vendorAdapter.setGenerateDdl(Boolean.TRUE); 
    vendorAdapter.setShowSql(Boolean.TRUE); 

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
    factory.setPersistenceUnitName("merchant"); 
    factory.setJpaVendorAdapter(vendorAdapter); 
    factory.setPackagesToScan("com.example.data.model"); 
    factory.setDataSource(dataSource); 

    factory.setJpaProperties(jpaProperties()); 
    factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver()); 

    return factory; 
} 

Properties jpaProperties() { 
    Properties props = new Properties(); 
    props.put("hibernate.query.substitutions", "true 'Y', false 'N'"); 
    props.put("hibernate.hbm2ddl.auto", "update"); 
    props.put("hibernate.show_sql", "false"); 
    props.put("hibernate.format_sql", "true"); 

    return props; 
} 

}

任何想法?

+0

你可以粘貼你的休眠設置嗎? –

+0

我剛剛更新了我的問題。 – yousafsajjad

+0

如何從您的生成器實現'find'方法? –

回答

3

問題是您沒有將所有需要的類添加到模式生成器。你可以這樣啓用它們:

for (Class<Object> clazz : getClasses(packageName)) { 
    cfg.addAnnotatedClass(clazz); 
} 

private List<Class> getClasses(String packageName) throws ClassNotFoundException { 
    List<Class> classes = new ArrayList<>(); 

    ClassLoader cld = Thread.currentThread().getContextClassLoader(); 

    String path = packageName.replace('.', '/'); 
    URL resource = cld.getResource(path); 

    File directory = new File(resource.getFile()); 

    if (!directory.exists()) { 
     throw new ClassNotFoundException(packageName + " is not a valid package"); 
    } 
    processDirectory(packageName, classes, directory); 

    return classes; 
}