Java 由于@ManyToOne关系,使用Hibernate架构导出器生成架构失败
我正在使用SchemaExporter生成ddl脚本Java 由于@ManyToOne关系,使用Hibernate架构导出器生成架构失败,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我正在使用SchemaExporter生成ddl脚本 public static void main(String[] args) throws Exception { SchemaDDLGenerator.execute(Dialect.ORACLE, Key.class); } 主要类别: @Entity public class Key extends AbstractEntity { private static final long serialVersionUI
public static void main(String[] args) throws Exception {
SchemaDDLGenerator.execute(Dialect.ORACLE, Key.class);
}
主要类别:
@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);
}
}
有什么想法吗?问题是您没有将所有需要的类添加到schema generator。您可以通过以下方式启用它们:
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;
}
for(类clazz:getClasses(packageName)){
cfg.addAnnotatedClass(clazz);
}
私有列表GetClass(字符串packageName)引发ClassNotFoundException{
列表类=新的ArrayList();
ClassLoader cld=Thread.currentThread().getContextClassLoader();
字符串路径=packageName.replace('.','/');
URL resource=cld.getResource(路径);
文件目录=新文件(resource.getFile());
如果(!directory.exists()){
抛出新的ClassNotFoundException(packageName+“不是有效的包”);
}
processDirectory(packageName、类、目录);
返回类;
}
你能粘贴你的hibernate设置吗?我刚刚更新了我的问题。如何从生成器中实现find
方法?我再次更新了问题以简化它。感谢您的回复。我认为问题在于您没有将所有模型类传递给execute方法。它需要包com.example.data.model中的所有类
@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;
}
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;
}