请参阅我的要求:使用SchemaExport导出已应用BeanValidation约束的数据库模式(例如,@ Length(32)将创建数据库约束:column(32))。
在Hibernate 4.1.x中,我可以在这里使用hack代码:https://forum.hibernate.org/viewtopic.php?f=1&t=1024911&view=previous
但是在Hibernate 4.3.5中删除了上述hack代码中所需的 Ejb3Configuration 类。
那么如何在不使用 Ejb3Configuration 的情况下导出应用BeanValidation约束的数据库模式?
答案 0 :(得分:1)
这样的事情应该有效:
PersistenceUnitDescriptorAdapter pu = new PersistenceUnitDescriptorAdapter() {
@Override
public List<String> getManagedClassNames() {
return Arrays.asList( MyClass.class.getName(), ... );
}
};
Map<Object, Object> settings = new HashMap<Object, Object>();
settings.put( "javax.persistence.schema-generation.scripts.action", "create" );
settings.put( "javax.persistence.schema-generation.scripts.create-target", "<path-to-export-file>" );
EntityManagerFactoryBuilderImpl factoryBuilder = new EntityManagerFactoryBuilderImpl( pu, settings );
factoryBuilder.generateSchema();
它依赖于Hibernate内部类,但您的早期解决方案也是如此。你可以在这里创建一个问题 - https://hibernate.onjira.com/browse/HHH - 解释你的用例。也许可以使用公共API的解决方案。
答案 1 :(得分:0)
我通过EntityManagerFactoryBuilderImpl使用HibernationConfiguration构建找到了一个临时解决方案。它使用JPA配置发出模式脚本(使用bean验证器约束)。
public final class JpaSchemaExporter
{
public JpaSchemaExporter(String utilName, String packageName, Properties properties, DialectType dialect,
Path outputPath) throws Exception
{
this.dialect = dialect;
this.outputPath = outputPath;
if (Files.exists(outputPath) && !Files.isDirectory(outputPath)) {
throw new IllegalArgumentException(
"Given path already exist and is not a directory! the path:" + outputPath);
}
Files.createDirectories(outputPath);
pud = new ParsedPersistenceXmlDescriptor(Resources.getResourceURL("META-INF"));
pud.setName(utilName);
pud.addClasses(Resources.getClasseNames(packageName));
pud.addMappingFiles("META-INF/orm.xml");
properties.setProperty("hibernate.dialect", dialect.getDialectClass());
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
factoryBuilder = new EntityManagerFactoryBuilderImpl( pud, properties );
factoryBuilder.withValidatorFactory(validatorFactory).build().close(); // create HibernateConfiguration instance
this.injectBeanValidationConstraintToDdlTranslator();
validatorFactory.close();
}
private void injectBeanValidationConstraintToDdlTranslator() {
try {
Configuration hibernateConfiguration = factoryBuilder.getHibernateConfiguration();
ValidatorFactory validatorFactory = (ValidatorFactory) factoryBuilder.getConfigurationValues().get(AvailableSettings.VALIDATION_FACTORY);
// private class in hibernate
Method applyRelationalConstraints = Class.forName("org.hibernate.cfg.beanvalidation.TypeSafeActivator")
.getMethod("applyRelationalConstraints",
ValidatorFactory.class,
java.util.Collection.class,
Properties.class,
Dialect.class);
applyRelationalConstraints.setAccessible(true);
Dialect dialectInstance = (Dialect) Class.forName(dialect.getDialectClass()).newInstance();
applyRelationalConstraints.invoke(null, validatorFactory,
Arrays.asList(Iterators.toArray(hibernateConfiguration.getClassMappings(), PersistentClass.class)) ,
hibernateConfiguration.getProperties(),
dialectInstance);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public void create() throws IOException {
Configuration cfg = factoryBuilder.getHibernateConfiguration();
cfg.setProperty("hibernate.hbm2ddl.auto", "create");
SchemaExport export = new SchemaExport(cfg);
export.setDelimiter(";");
export.setOutputFile(Paths.get(outputPath.toString(), "ddl_create_" + dialect.name().toLowerCase() + ".sql").toString());
export.execute(true, false, false, true);
if (!export.getExceptions().isEmpty()) {
System.out.println();
System.out.println("SOME EXCEPTIONS OCCURED WHILE GENERATING THE UPDATE SCRIPT:");
for (Exception e : (List<Exception>) export.getExceptions()) {
System.out.println(e.getMessage());
}
}
}
@SuppressWarnings("unchecked")
public void update() throws IOException {
Configuration cfg = factoryBuilder.getHibernateConfiguration();
cfg.setProperty("hibernate.hbm2ddl.auto", "update");
SchemaUpdate updater = new SchemaUpdate(cfg);
updater.setDelimiter(";");
updater.setOutputFile(Paths.get(outputPath.toString(), "ddl_update_" + dialect.name().toLowerCase() + ".sql").toString());
updater.execute(true, false);
if (!updater.getExceptions().isEmpty()) {
System.out.println();
System.out.println("SOME EXCEPTIONS OCCURED WHILE GENERATING THE UPDATE SCRIPT:");
for (Exception e : ((List<Exception>) updater.getExceptions())) {
System.out.println(e.getMessage());
}
}
}
public void validate() {
Configuration hibernateConfiguration = factoryBuilder.getHibernateConfiguration();
hibernateConfiguration.setProperty("hibernate.hbm2ddl.auto", "validate");
SchemaValidator validator = new SchemaValidator(hibernateConfiguration);
validator.validate();
}
public static void main(String[] args) throws Exception {
Properties prop = new Properties(System.getProperties());
prop.setProperty("hibernate.connection.driver_class", "value in your env");
prop.setProperty("hibernate.connection.url", "value in your env");
prop.setProperty("hibernate.connection.username", "value in your env");
prop.setProperty("hibernate.connection.password", "value in your env");
Path path = Paths.get("schema output path in your env");
String packageName = prop.getProperty("package names of jpa classes");
String unitName = prop.getProperty("jpa Unit Name");
String[] dialects = "HSQL,MYSQL".split(",");
for(String dialect : dialects){
DialectType dialectType = DialectType.valueOf(dialect);
JpaSchemaExporter ddlExporter = new JpaSchemaExporter(unitName, packageName, prop, dialectType, path);
ddlExporter.update();
ddlExporter.create();
}
}
}