Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将Hibernate SchemaUpdate类与JPA persistence.xml一起使用?_Hibernate_Jpa_Persistence.xml - Fatal编程技术网

如何将Hibernate SchemaUpdate类与JPA persistence.xml一起使用?

如何将Hibernate SchemaUpdate类与JPA persistence.xml一起使用?,hibernate,jpa,persistence.xml,Hibernate,Jpa,Persistence.xml,我有一个主要方法,使用SchemaUpdate在控制台上显示要更改/创建的表,它在我的Hibernate项目中运行良好: public static void main(String[] args) throws IOException { //first we prepare the configuration Properties hibProps = new Properties(); hibProps.load(Thread.currentThread().getConte

我有一个主要方法,使用SchemaUpdate在控制台上显示要更改/创建的表,它在我的Hibernate项目中运行良好:

 public static void main(String[] args) throws IOException {
  //first we prepare the configuration
  Properties hibProps = new Properties();
  hibProps.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("jbbconfigs.properties"));
  Configuration cfg = new AnnotationConfiguration();
  cfg.configure("/hibernate.cfg.xml").addProperties(hibProps);

  //We create the SchemaUpdate thanks to the configs
  SchemaUpdate schemaUpdate = new SchemaUpdate(cfg);


  //The update is executed in script mode only
  schemaUpdate.execute(true, false);
  ...  
我希望在JPA项目中重用这段代码,没有hibernate.cfg.xml文件(也没有.properties文件),只有persistence.xml文件(在JPA规范指定的META-INF目录中自动检测到)

我试过这个太简单的改编

Configuration cfg = new AnnotationConfiguration();
cfg.configure();
但它失败了,只有一个例外

Exception in thread "main" org.hibernate.HibernateException: /hibernate.cfg.xml not found
有人这样做过吗?
谢谢。

您应该使用ejb3配置而不是普通配置。请参阅hibernate文档末尾的entity manager文档

(从上述来源复制,稍作修改)

正如您所看到的,您可以混合许多不同类型的配置

如果它仅用于模式更新部分,则可以在persistence.xml中设置一个属性:
hibernate.hbm2ddl.auto

<persistence-unit name="app1">
   <provider>org.hibernate.ejb.HibernatePersistence</provider>
   <properties>
     …
     <property name="hibernate.hbm2ddl.auto" value="update"/>
   </properties>
</properties>

org.hibernate.ejb.HibernatePersistence
…


有关更多参考资料,请参阅。

卡里姆的做法是正确的,但让我尝试澄清一下

假设您有一个普通的JPA标准配置,除了类路径上的Hibernate JAR之外,没有特定于Hibernate的配置。如果您在J2SE引导模式下运行,那么您已经有了一些类似于以下内容的代码,无论是Java还是Spring配置,等等:

Map<String, Object> props = getJPAProperties();
EntityManagerFactory emf = 
    Persistence.createEntityManagerFactory("persistence-unit-name", props);
Map props=getJPAProperties();
EntityManagerFactory emf=
createEntityManagerFactory(“持久化单元名称”,props);
要运行SchemaUpdate,只需使用以下命令:

Map<String, Object> props = getJPAProperties();
Ejb3Configuration conf = 
    new Ejb3Configuration().configure("persistence-unit-name", props);
new SchemaUpdate(conf.getHibernateConfiguration()).execute(true, false);
Map props=getJPAProperties();
EJB3配置配置=
新的Ejb3Configuration().configure(“持久化单元名称”,props);
新的SchemaUpdate(conf.getHibernateConfiguration()).execute(true,false);

我不确定这在容器环境中会如何运行,但在简单的J2SE或Spring类型的配置中,这就是它的全部。

非常感谢Peter,您的回复很好。 下面是SchemaUpdater类的完整代码:

package reformyourcountry.dbupdate;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;

import reformyourcountry.misc.DateUtil;

/** Small utility to be run by a developer to identify the difference between
 * its entities and its DB schema. It produces an SQL to be copy/pasted and applied
 * on the DB manually. Each developers having its own DB, when a developer commits its
 * Java code with new entity attributes (needing new DB columns), he also commits
 * an updated SQL file with the SQL that other developers need to apply on their local DB.
 * Later, when deploying the next version of the application in production,
 * this SQL file with cumulated changes will be applied onto the production DB.  
 * 
 * Limitations: 
 * 1. the Hibernate schema update does not detect removed attributes. 
 * If you have to delete a column, you need to write the SQL manually;
 * 
 * 2. the Hibernate schema update does not detect changes on existing columns.
 * for example, if you add @Column(nullable=false), it will not generates an 
 * additional DB constraint.
 * 
 * @author Cédric Fieux & John Rizzo & Aymeric Levaux
 *
 */
public class SchemaUpdater  {

    @SuppressWarnings({ "deprecation", "unchecked" })
    public static void main(String[] arg) throws IOException {

        ////// 1. Prepare the configuration (connection parameters to the DB, ect.)
        // Empty map. We add no additional property, everything is already in the persistence.xml
        Map<String,Object> map=new HashMap<String,Object>();   
        // Get the config from the persistence.xml file, with the unit name as parameter.
        Ejb3Configuration conf =  new Ejb3Configuration().configure("ConnectionPostgres",map);
        SchemaUpdate schemaUpdate =new SchemaUpdate(conf.getHibernateConfiguration());

        /////// 2. Get the SQL
        // Before we run the update, we start capturing the console output (to add ";" later)
        PrintStream initOut = System.out;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
        PrintStream newOut = new PrintStream(outputStream);
        System.setOut(newOut);

        //The update is executed in script mode only
        schemaUpdate.execute(true, false);

        //We reset the original out
        System.setOut(initOut);

        ////// 3. Prints that SQL at the console with a good format (adding a ";" after each line).
        System.out.println("--*******************************************Begin of SQL********************************************");
        System.out.println("-- "+DateUtil.formatyyyyMMdd(new Date()));
        BufferedReader ouReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(outputStream.toByteArray())));
        String str = ouReader.readLine();
        while(str != null){  // For each (sometimes multiline) SQL statement
            // now, str equals "".
            str = ouReader.readLine();  // 
            while (str != null && !str.trim().equals("")) { // for each line of the same statement
                System.out.println();  // previous line is finished.
                System.out.print(str.toLowerCase());
                str = ouReader.readLine();
            }
            // Statement is now finished
            System.out.println(";");
        }
        System.out.println("--*******************************************End of SQL********************************************");

        ////// 4. Print eventual exceptions.
        //If some exception occurred we display them
        if(!schemaUpdate.getExceptions().isEmpty()){
            System.out.println();
            System.out.println("SOME EXCEPTIONS OCCURED WHILE GENERATING THE UPDATE SCRIPT:");
            for (Exception e: (List<Exception>)schemaUpdate.getExceptions()) {
                System.out.println(e.getMessage());
            }
        }
    }

}
包reformyourcountry.dbupdate;
导入java.io.BufferedReader;
导入java.io.ByteArrayInputStream;
导入java.io.ByteArrayOutputStream;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.io.PrintStream;
导入java.util.Date;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入org.hibernate.ejb.ejb3配置;
导入org.hibernate.tool.hbm2ddl.SchemaUpdate;
导入reformyourcountry.misc.DateUtil;
/**由开发人员运行的小实用程序,用于识别
*它的实体和数据库模式。它生成要复制/粘贴和应用的SQL
*手动打开数据库。当开发人员提交其数据库时,每个开发人员都有自己的数据库
*Java代码具有新的实体属性(需要新的DB列),他还提交
*一个更新的SQL文件,其中包含其他开发人员需要在其本地数据库上应用的SQL。
*稍后,在生产环境中部署应用程序的下一个版本时,
*此SQL文件及其累积更改将应用于生产数据库。
* 
*限制:
* 1. Hibernate架构更新未检测到已删除的属性。
*如果需要删除一列,则需要手动编写SQL;
* 
* 2. Hibernate架构更新不会检测现有列上的更改。
*例如,如果添加@Column(nullable=false),它将不会生成
*附加DB约束。
* 
*@Cédric Fieux和John Rizzo以及Aymeric Levaux的作者
*
*/
公共类SchemaUpdater{
@SuppressWarnings({“弃用”、“未选中”})
公共静态void main(字符串[]arg)引发IOException{
//////1.准备配置(连接数据库的参数等)
//空映射。我们不添加其他属性,所有内容都已在persistence.xml中
Map Map=newhashmap();
//从persistence.xml文件获取配置,单元名称作为参数。
Ejb3Configuration=newejb3configuration().configure(“ConnectionPostgres”,map);
SchemaUpdate SchemaUpdate=新的SchemaUpdate(conf.getHibernateConfiguration());
///////2.获取SQL
//在运行更新之前,我们开始捕获控制台输出(稍后添加“;”)
PrintStream initOut=System.out;
ByteArrayOutputStream outputStream=新的ByteArrayOutputStream(1024);
PrintStream newOut=新的PrintStream(outputStream);
系统放样(新放样);
//更新仅在脚本模式下执行
schemaUpdate.execute(true,false);
//我们重新设置了原始数据
系统放样(初始放样);
//////3.在控制台以良好的格式打印该SQL(在每行后面添加“;”。
System.out.println(“--************************************************************************************************************************************************************************************************************************************************************************************SQL的开始部分”);
System.out.println(“--”+DateUtil.formatyyyyMMdd(new Date());
BufferedReader-OureReader=new BufferedReader(new InputStreamReader(new ByteArrayInputStream(outputStream.toByteArray()));
String str=ouReader.readLine();
而(str!=null){//对于每个(有时是多行)SQL语句
//现在,str等于“”。
str=ouReader.readLine();//
而(str!=null&&!str.trim().equals(“”){//对于同一语句的每一行
System.out.println();//上一行已完成。
System.out.print(str.toLowerCase());
str=ouReader.readLine();
}
//语句现在已完成
System.out.println(“;”);
}
System.out.println(“--***************************************************************************************************************************************************************************************************************************************************************”结束SQL语句);
//////4.打印最终的例外情况。
//如果出现异常,我们将显示它们
如果(!s
package reformyourcountry.dbupdate;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;

import reformyourcountry.misc.DateUtil;

/** Small utility to be run by a developer to identify the difference between
 * its entities and its DB schema. It produces an SQL to be copy/pasted and applied
 * on the DB manually. Each developers having its own DB, when a developer commits its
 * Java code with new entity attributes (needing new DB columns), he also commits
 * an updated SQL file with the SQL that other developers need to apply on their local DB.
 * Later, when deploying the next version of the application in production,
 * this SQL file with cumulated changes will be applied onto the production DB.  
 * 
 * Limitations: 
 * 1. the Hibernate schema update does not detect removed attributes. 
 * If you have to delete a column, you need to write the SQL manually;
 * 
 * 2. the Hibernate schema update does not detect changes on existing columns.
 * for example, if you add @Column(nullable=false), it will not generates an 
 * additional DB constraint.
 * 
 * @author Cédric Fieux & John Rizzo & Aymeric Levaux
 *
 */
public class SchemaUpdater  {

    @SuppressWarnings({ "deprecation", "unchecked" })
    public static void main(String[] arg) throws IOException {

        ////// 1. Prepare the configuration (connection parameters to the DB, ect.)
        // Empty map. We add no additional property, everything is already in the persistence.xml
        Map<String,Object> map=new HashMap<String,Object>();   
        // Get the config from the persistence.xml file, with the unit name as parameter.
        Ejb3Configuration conf =  new Ejb3Configuration().configure("ConnectionPostgres",map);
        SchemaUpdate schemaUpdate =new SchemaUpdate(conf.getHibernateConfiguration());

        /////// 2. Get the SQL
        // Before we run the update, we start capturing the console output (to add ";" later)
        PrintStream initOut = System.out;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
        PrintStream newOut = new PrintStream(outputStream);
        System.setOut(newOut);

        //The update is executed in script mode only
        schemaUpdate.execute(true, false);

        //We reset the original out
        System.setOut(initOut);

        ////// 3. Prints that SQL at the console with a good format (adding a ";" after each line).
        System.out.println("--*******************************************Begin of SQL********************************************");
        System.out.println("-- "+DateUtil.formatyyyyMMdd(new Date()));
        BufferedReader ouReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(outputStream.toByteArray())));
        String str = ouReader.readLine();
        while(str != null){  // For each (sometimes multiline) SQL statement
            // now, str equals "".
            str = ouReader.readLine();  // 
            while (str != null && !str.trim().equals("")) { // for each line of the same statement
                System.out.println();  // previous line is finished.
                System.out.print(str.toLowerCase());
                str = ouReader.readLine();
            }
            // Statement is now finished
            System.out.println(";");
        }
        System.out.println("--*******************************************End of SQL********************************************");

        ////// 4. Print eventual exceptions.
        //If some exception occurred we display them
        if(!schemaUpdate.getExceptions().isEmpty()){
            System.out.println();
            System.out.println("SOME EXCEPTIONS OCCURED WHILE GENERATING THE UPDATE SCRIPT:");
            for (Exception e: (List<Exception>)schemaUpdate.getExceptions()) {
                System.out.println(e.getMessage());
            }
        }
    }

}