问题描述
我发现的大多数答案都使用 javax.persistence.schema-generation
属性。例如。
create table ...(...)
create table ...(...)
我希望它输出分隔符;
create table ...(...);
创建表...(...);
但我找不到任何 javax.persistence.schema-generation
属性来配置它。
所以我想用,因为您可以。但是为了创建一个 SchemaExport
我需要一个 MetadataImplementor
(非deprected api)。
我无法弄清楚如何从spring引导中获取 MetadataImplementor
。
有没有人知道是否存在
javax.persistence.schema-generation
属性定义分隔符
SchemaExport
(获取依赖关系)
@SpringBootApplication
@ComponentScan(basePackageClasses = Application.class)
@EntityScan(basePackageClasses = User.class)
public class Application {
@Bean
public ApplicationRunner getApplicationRunner(){
返回新的ApplicationRunner(){
public void run(ApplicationArguments args )抛出异常{
// MetadataImplementor或metadataImplementor = ???;
//新建SchemaExport(metadataImplementor);
}
};
public static void main(String [] args){
SpringApplication application = new SpringApplication(Application.class);
application.run(args);
}
}
@实体
公共类用户{
@Id
@GeneratedValue
私人长ID;
私人字符串名称;
public Long getId(){
return id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
@Entity
public class Person {
@Id
@GeneratedValue
私人长ID;
私人字符串名称;
public Long getId(){
return id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
// application.properties
spring.jpa.properties.javax.persistence.schema-generation.create -source =元数据
spring.jpa.properties.javax.persistence.schema-generation.scripts.action =创建
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target = create.sql
// maven dependencies
< spring.boot.version> 1.4.3.RELEASE< /spring.boot.version>
< / properties>
< dependencyManagement>
<依赖关系>
< dependency>
< groupId> org.springframework.boot< / groupId>
< artifactId> spring-boot-dependencies< / artifactId>
< version> $ {spring.boot.version}< / version>
< type> pom< / type>
< scope> import< / scope>
< /依赖关系>
< /依赖关系>
< / dependencyManagement>
<依赖关系>
< dependency>
< groupId> org.springframework.boot< / groupId>
< artifactId> spring-boot-starter-data-jpa< / artifactId>
< /依赖关系>
< dependency>
< groupId> com.h2database< / groupId>
< artifactId> h2< / artifactId>
< /依赖关系>
< /依赖关系>
使用Hibernate 5.0
我只是用hibernate 5.0.11.Final
来试过上面的代码。您必须更改的唯一方法是
$ b $ pre $ code> SchemaExport schemaExport = new SchemaExport((MetadataImplementor)metadata);
schemaExport.setDelimiter(;);
schemaExport.setFormat(false);
schemaExport.setOutputFile(dropAndCreateDdlFile.getAbsolutePath());
schemaExport.execute(true,false,false,false);
或者当然让java配置返回一个 MetadataImplementor
代替元数据
并更改 ApplicationRunner
构造函数参数。
最后经过很多调查,我想我找到了一个使用公共API的简单解决方案。我找到的解决方案使用hibernate 5.2
(更具体的 5.2.6.Final
)。但我认为它也可以适用于 5.0
这里是我的spring java配置
@Configuration
@AutoConfigureAfter({HibernateJpaAutoConfiguration.class})
public class HibernateJavaConfig {
@ ConditionalOnMissingBean({Metadata.class})
@Bean
public Metadata getMetadata(StandardServiceRegistry standardServiceRegistry,
PersistenceUnitInfo persistenceUnitInfo){
MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
列表< String> managedClassNames = persistenceUnitInfo.getManagedClassNames();
for(String managedClassName:managedClassNames){
metadataSources.addAnnotatedClassName(managedClassName);
}
元数据元数据= metadataSources.buildMetadata();
返回元数据; (StandardServiceRegistry.class)
@Bean
public StandardServiceRegistry getStandardServiceRegistry(JpaProperties jpaProperties) );
地图< String,String> properties = jpaProperties.getProperties();
ssrb.applySettings(properties);
StandardServiceRegistry ssr = ssrb.build();
返回ssr; $ {
}
@ConditionalOnMissingBean({PersistenceUnitInfo.class})
@Bean
public PersistenceUnitInfo getPersistenceUnitInfo(EntityScanPackages entityScanPackages){
List< String> packagesToScan = entityScanPackages.getPackageNames();
DefaultPersistenceUnitManager persistenceUnitManager = new DefaultPersistenceUnitManager();
String [] packagesToScanArr =(String [])packagesToScan.toArray(new String [packagesToScan.size()]);
persistenceUnitManager.setPackagesToScan(packagesToScanArr);
persistenceUnitManager.afterPropertiesSet();
PersistenceUnitInfo persistenceUnitInfo = persistenceUnitManager.obtainDefaultPersistenceUnitInfo();
返回persistenceUnitInfo;
}
}
java配置创建一个 Metadata
bean。这个bean可以在hibernate 5.2中用来执行模式生成。例如,
pre $ @Component
public class GenerateDDLApplicationRunner实现ApplicationRunner {
私有元数据元数据;
public GenerateDDLApplicationRunner(元数据元数据){
this.metadata = metadata;
}
public void run(ApplicationArguments args)throws Exception {
文件dropAndCreateDdlFile = new File(drop-and-create.ddl);
deleteFileIfExists(dropAndCreateDdlFile);
SchemaExport schemaExport = new SchemaExport();
schemaExport.setDelimiter(;);
schemaExport.setFormat(false);
schemaExport.setOutputFile(dropAndCreateDdlFile.getAbsolutePath());
schemaExport.execute(EnumSet.of(TargetType.SCRIPT),Action.BOTH,metadata);
}
private void deleteFileIfExists(File dropAndCreateDdlFile){
if(dropAndCreateDdlFile.exists()){
if(!dropAndCreateDdlFile.isFile()){
String msg = MessageFormat.format(File is not a normal file {0},dropAndCreateDdlFile);
抛出新的IllegalStateException(msg); $!
$ b if(!dropAndCreateDdlFile.delete()){
String msg = MessageFormat.format(Unable to delete file {0},dropAndCreateDdlFile);
抛出新的IllegalStateException(msg);
}
}
}
}
hibernate方言是使用spring boot application.properties
配置的。在我的情况下:
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL57InnoDBDialect
I want generate create and drop ddl scripts using spring boot v1.4.3 with JPA - Hibernate 5.0.11.
Most answers I found use the javax.persistence.schema-generation
properties. E.g. https://stackoverflow.com/a/36966419/974186
The problem with this approach is the it outputs the sql statements without an delimiter. E.g.
create table ... (...)
create table ... (...)
I want it to output the statements with the delimiter ;
create table ... (...);
create table ... (...);
But I can't find any javax.persistence.schema-generation
property to configure it.
So I thought to use the SchemaExport
from hibernate, because you can set the delimiter property. But to create a SchemaExport
I need a MetadataImplementor
(non deprected api).
I can not figure out how to get a MetadataImplementor
from spring boot.
Does anyone know if there is either
- a
javax.persistence.schema-generation
property to define the delimiter - or how to create a
SchemaExport
(get the dependencies) - or has another solution?
Here is some code you can play with
@SpringBootApplication
@ComponentScan(basePackageClasses = Application.class)
@EntityScan(basePackageClasses = User.class)
public class Application {
@Bean
public ApplicationRunner getApplicationRunner() {
return new ApplicationRunner() {
public void run(ApplicationArguments args) throws Exception {
// MetadataImplementor metadataImplementor = ???;
// new SchemaExport(metadataImplementor);
}
};
}
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
application.run(args);
}
}
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// application.properties
spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql
// maven dependencies
<properties>
<spring.boot.version>1.4.3.RELEASE</spring.boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
With Hibernate 5.0
I just tried the code above with hibernate 5.0.11.Final
. The only thing you must change is
SchemaExport schemaExport = new SchemaExport((MetadataImplementor) metadata);
schemaExport.setDelimiter(";");
schemaExport.setFormat(false);
schemaExport.setOutputFile(dropAndCreateDdlFile.getAbsolutePath());
schemaExport.execute(true, false, false, false);
or of course let the java configuration return a MetadataImplementor
instead of Metadata
and change the ApplicationRunner
constructor param.
Finally after a lot of investigation I think I found an easy solution that uses public APIs. The solution I found uses hibernate 5.2
(more concrete 5.2.6.Final
). But I think it can also be adapted to 5.0
Here is my spring java configuration
@Configuration
@AutoConfigureAfter({ HibernateJpaAutoConfiguration.class })
public class HibernateJavaConfig {
@ConditionalOnMissingBean({ Metadata.class })
@Bean
public Metadata getMetadata(StandardServiceRegistry standardServiceRegistry,
PersistenceUnitInfo persistenceUnitInfo) {
MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
List<String> managedClassNames = persistenceUnitInfo.getManagedClassNames();
for (String managedClassName : managedClassNames) {
metadataSources.addAnnotatedClassName(managedClassName);
}
Metadata metadata = metadataSources.buildMetadata();
return metadata;
}
@ConditionalOnMissingBean({ StandardServiceRegistry.class })
@Bean
public StandardServiceRegistry getStandardServiceRegistry(JpaProperties jpaProperties) {
StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder();
Map<String, String> properties = jpaProperties.getProperties();
ssrb.applySettings(properties);
StandardServiceRegistry ssr = ssrb.build();
return ssr;
}
@ConditionalOnMissingBean({ PersistenceUnitInfo.class })
@Bean
public PersistenceUnitInfo getPersistenceUnitInfo(EntityScanPackages entityScanPackages) {
List<String> packagesToScan = entityScanPackages.getPackageNames();
DefaultPersistenceUnitManager persistenceUnitManager = new DefaultPersistenceUnitManager();
String[] packagesToScanArr = (String[]) packagesToScan.toArray(new String[packagesToScan.size()]);
persistenceUnitManager.setPackagesToScan(packagesToScanArr);
persistenceUnitManager.afterPropertiesSet();
PersistenceUnitInfo persistenceUnitInfo = persistenceUnitManager.obtainDefaultPersistenceUnitInfo();
return persistenceUnitInfo;
}
}
The java configuration creates a Metadata
bean. This bean can be used in hibernate 5.2 to execute a schema generation. E.g.
@Component
public class GenerateDDLApplicationRunner implements ApplicationRunner {
private Metadata metadata;
public GenerateDDLApplicationRunner(Metadata metadata) {
this.metadata = metadata;
}
public void run(ApplicationArguments args) throws Exception {
File dropAndCreateDdlFile = new File("drop-and-create.ddl");
deleteFileIfExists(dropAndCreateDdlFile);
SchemaExport schemaExport = new SchemaExport();
schemaExport.setDelimiter(";");
schemaExport.setFormat(false);
schemaExport.setOutputFile(dropAndCreateDdlFile.getAbsolutePath());
schemaExport.execute(EnumSet.of(TargetType.SCRIPT), Action.BOTH, metadata);
}
private void deleteFileIfExists(File dropAndCreateDdlFile) {
if (dropAndCreateDdlFile.exists()) {
if (!dropAndCreateDdlFile.isFile()) {
String msg = MessageFormat.format("File is not a normal file {0}", dropAndCreateDdlFile);
throw new IllegalStateException(msg);
}
if (!dropAndCreateDdlFile.delete()) {
String msg = MessageFormat.format("Unable to delete file {0}", dropAndCreateDdlFile);
throw new IllegalStateException(msg);
}
}
}
}
The hibernate dialect is configured using the spring boot application.properties
. In my case:
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL57InnoDBDialect
这篇关于使用自定义分隔符通过弹簧引导生成DDL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!