如何 运行 独立的 Hibernate 4 SchemaExport 与 Java Spring 配置
How to run standalone Hibernate 4 SchemaExport with Java Spring config
我们有一个 Java Spring 项目,使用 JPA 和 Hibernate 4 for ORM。我们专门使用 Java 配置,因此我们没有任何 hibernate.properties 或 persistence.xml 映射文件。
我们还使用 Spring 的 Jsr310JpaConverters 和一些实现 javax.persistence.AttributeConverter
的自定义属性转换器。包扫描会自动拾取自定义转换器。
除此之外,我们的设置还算标准,基本上就是
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackageClasses = BasePackageMarker.class, repositoryBaseClass = InternalRepositoryImpl.class)
public class JpaConfig {
// values loaded from property file
public Properties jpaProperties() {
Properties jpaProperties = new Properties();
jpaProperties.setProperty(Environment.DIALECT, dialect);
jpaProperties.setProperty(Environment.HBM2DDL_AUTO, getHbm2ddlAuto());
// ...
return jpaProperties;
}
@Bean
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setDriverClassName(driver);
config.setJdbcUrl(url);
config.setUsername(username);
config.setPassword(password);
// ...
return new HikariDataSource(config);
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setPackagesToScan(
BasePackageMarker.class.getPackage().getName(),
Jsr310JpaConverters.class.getPackage().getName()
);
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setJpaProperties(jpaProperties());
return entityManagerFactoryBean;
}
// ...
}
我正在寻找一种方法 运行 Hibernate 的 SchemaExport 来创建我们的数据库模式,无需 运行ning Tomcat 或 Spring 应用程序,具有相同的配置为使用 hbm2ddl=create
启动应用程序,特别是查找所有实体 类 和属性转换器。我想 运行 它与 Maven,但一旦我知道从哪里开始,我就可以弄清楚那部分。
我发现了许多针对 Hibernate 3 或 XML 配置的过时答案和库,似乎对我们的设置不起作用。我确定答案已经在那里,但在这一点上我很困惑,不知道该尝试什么。任何解决方案或指示?
我认为您需要使用 AnnotationConfiguration():
在hibernate中,不使用hibernate.cfg.xml也可以实现数据库连接。在hibernate注解中,有一个名为AnnotationConfiguration的class。 AnnotationConfiguration 提供配置数据库属性的方法。
AnnotationConfiguration 有不同的方法,如 .addAnnotatedClass、.addProperties 等。有 .configure() 方法寻求 hibernate.cfg,如果我们不打算使用 hibernate.cfg,则不需要使用 .configure() .
假设我有实体用户
package com.persistence;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue
private int id;
@Column(name="name")
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
HibernateUtil class
public class HibernateUtil {
private static final SessionFactory concreteSessionFactory;
static {
try {
Properties prop= new Properties();
prop.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernate");
prop.setProperty("hibernate.connection.username", "root");
prop.setProperty("hibernate.connection.password", "");
prop.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
prop.setProperty("hbm2ddl.auto", "create");
concreteSessionFactory = new AnnotationConfiguration()
.addPackage("com.persistence")
.addProperties(prop)
.addAnnotatedClass(User.class)
.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession()
throws HibernateException {
return concreteSessionFactory.openSession();
}
public static void main(String... args){
Session session=getSession();
session.beginTransaction();
User user=(User)session.get(User.class, new Integer(1));
System.out.println(user.getName());
session.close();
}
}
这是我根据 Bhushan Uniyal 的回答得出的解决方案。使用反射找到我们的实体和属性转换器。
public static void main(String... args) {
Properties prop = new Properties();
prop.setProperty("hibernate.connection.url", "jdbc:mysql://127.0.0.1:3306/db");
prop.setProperty("hibernate.connection.username", "user");
prop.setProperty("hibernate.connection.password", "xxxx");
prop.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
prop.setProperty("hibernate.hbm2ddl.auto", "create");
Configuration cfg = new Configuration()
.addPackage("com.persistence")
.addProperties(prop);
Reflections basePackageReflections = new Reflections(BasePackageMarker.class.getPackage().getName());
for (Class<?> entityClass : basePackageReflections.getTypesAnnotatedWith(Entity.class)) {
System.out.println("Adding entity class: " + entityClass.getSimpleName());
cfg.addAnnotatedClass(entityClass);
}
for (Class<? extends AttributeConverter> attributeConverter : basePackageReflections.getSubTypesOf(AttributeConverter.class)) {
System.out.println("Adding attribute converter: " + attributeConverter.getSimpleName());
cfg.addAttributeConverter(attributeConverter);
}
cfg.addAttributeConverter(Jsr310JpaConverters.LocalDateConverter.class);
cfg.addAttributeConverter(Jsr310JpaConverters.LocalDateTimeConverter.class);
cfg.addAttributeConverter(Jsr310JpaConverters.LocalTimeConverter.class);
cfg.addAttributeConverter(Jsr310JpaConverters.InstantConverter.class);
new SchemaExport(cfg).create(true, true);
}
我们有一个 Java Spring 项目,使用 JPA 和 Hibernate 4 for ORM。我们专门使用 Java 配置,因此我们没有任何 hibernate.properties 或 persistence.xml 映射文件。
我们还使用 Spring 的 Jsr310JpaConverters 和一些实现 javax.persistence.AttributeConverter
的自定义属性转换器。包扫描会自动拾取自定义转换器。
除此之外,我们的设置还算标准,基本上就是
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackageClasses = BasePackageMarker.class, repositoryBaseClass = InternalRepositoryImpl.class)
public class JpaConfig {
// values loaded from property file
public Properties jpaProperties() {
Properties jpaProperties = new Properties();
jpaProperties.setProperty(Environment.DIALECT, dialect);
jpaProperties.setProperty(Environment.HBM2DDL_AUTO, getHbm2ddlAuto());
// ...
return jpaProperties;
}
@Bean
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setDriverClassName(driver);
config.setJdbcUrl(url);
config.setUsername(username);
config.setPassword(password);
// ...
return new HikariDataSource(config);
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setPackagesToScan(
BasePackageMarker.class.getPackage().getName(),
Jsr310JpaConverters.class.getPackage().getName()
);
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setJpaProperties(jpaProperties());
return entityManagerFactoryBean;
}
// ...
}
我正在寻找一种方法 运行 Hibernate 的 SchemaExport 来创建我们的数据库模式,无需 运行ning Tomcat 或 Spring 应用程序,具有相同的配置为使用 hbm2ddl=create
启动应用程序,特别是查找所有实体 类 和属性转换器。我想 运行 它与 Maven,但一旦我知道从哪里开始,我就可以弄清楚那部分。
我发现了许多针对 Hibernate 3 或 XML 配置的过时答案和库,似乎对我们的设置不起作用。我确定答案已经在那里,但在这一点上我很困惑,不知道该尝试什么。任何解决方案或指示?
我认为您需要使用 AnnotationConfiguration(): 在hibernate中,不使用hibernate.cfg.xml也可以实现数据库连接。在hibernate注解中,有一个名为AnnotationConfiguration的class。 AnnotationConfiguration 提供配置数据库属性的方法。 AnnotationConfiguration 有不同的方法,如 .addAnnotatedClass、.addProperties 等。有 .configure() 方法寻求 hibernate.cfg,如果我们不打算使用 hibernate.cfg,则不需要使用 .configure() .
假设我有实体用户
package com.persistence;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue
private int id;
@Column(name="name")
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
HibernateUtil class
public class HibernateUtil {
private static final SessionFactory concreteSessionFactory;
static {
try {
Properties prop= new Properties();
prop.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernate");
prop.setProperty("hibernate.connection.username", "root");
prop.setProperty("hibernate.connection.password", "");
prop.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
prop.setProperty("hbm2ddl.auto", "create");
concreteSessionFactory = new AnnotationConfiguration()
.addPackage("com.persistence")
.addProperties(prop)
.addAnnotatedClass(User.class)
.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession()
throws HibernateException {
return concreteSessionFactory.openSession();
}
public static void main(String... args){
Session session=getSession();
session.beginTransaction();
User user=(User)session.get(User.class, new Integer(1));
System.out.println(user.getName());
session.close();
}
}
这是我根据 Bhushan Uniyal 的回答得出的解决方案。使用反射找到我们的实体和属性转换器。
public static void main(String... args) {
Properties prop = new Properties();
prop.setProperty("hibernate.connection.url", "jdbc:mysql://127.0.0.1:3306/db");
prop.setProperty("hibernate.connection.username", "user");
prop.setProperty("hibernate.connection.password", "xxxx");
prop.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
prop.setProperty("hibernate.hbm2ddl.auto", "create");
Configuration cfg = new Configuration()
.addPackage("com.persistence")
.addProperties(prop);
Reflections basePackageReflections = new Reflections(BasePackageMarker.class.getPackage().getName());
for (Class<?> entityClass : basePackageReflections.getTypesAnnotatedWith(Entity.class)) {
System.out.println("Adding entity class: " + entityClass.getSimpleName());
cfg.addAnnotatedClass(entityClass);
}
for (Class<? extends AttributeConverter> attributeConverter : basePackageReflections.getSubTypesOf(AttributeConverter.class)) {
System.out.println("Adding attribute converter: " + attributeConverter.getSimpleName());
cfg.addAttributeConverter(attributeConverter);
}
cfg.addAttributeConverter(Jsr310JpaConverters.LocalDateConverter.class);
cfg.addAttributeConverter(Jsr310JpaConverters.LocalDateTimeConverter.class);
cfg.addAttributeConverter(Jsr310JpaConverters.LocalTimeConverter.class);
cfg.addAttributeConverter(Jsr310JpaConverters.InstantConverter.class);
new SchemaExport(cfg).create(true, true);
}