【问题标题】:Generating DDL script for Hibernate 4 / JPA 2.1 requires JDBC connection为 Hibernate 4 / JPA 2.1 生成 DDL 脚本需要 JDBC 连接
【发布时间】:2015-05-07 14:59:15
【问题描述】:

我一定遗漏了一些东西:尝试从 Hibernate 4 / JPA 2.1 生成 DDL 脚本。做了研究,发现以下代码失败并出现“应用程序必须提供 JDBC 连接”错误:

public class JpaSchemaExport {

public static void main(String[] args) throws IOException {
    execute(args[0], args[1]);
    System.exit(0);
}

public static void execute(String persistenceUnitName, String destination) {
    System.out.println("Generating DDL create script to : " + destination);

    final Properties persistenceProperties = new Properties();

    // XXX force persistence properties : remove database target
    persistenceProperties.setProperty(
            org.hibernate.cfg.AvailableSettings.HBM2DDL_AUTO, "");
    persistenceProperties.setProperty(
            AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "none");

    // XXX force persistence properties : define create script target from
    // metadata to destination
    // persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_CREATE_SCHEMAS,
    // "true");
    persistenceProperties.setProperty(
            AvailableSettings.SCHEMA_GEN_SCRIPTS_ACTION, "create");
    persistenceProperties.setProperty(
            AvailableSettings.SCHEMA_GEN_CREATE_SOURCE, "metadata");
    persistenceProperties
            .setProperty(
                    AvailableSettings.SCHEMA_GEN_SCRIPTS_CREATE_TARGET,
                    destination);

    // Persistence.generateSchema(persistenceUnitName, null);
    Persistence.generateSchema(persistenceUnitName, persistenceProperties);
}

}

问题是,如果只需要生成 DDL(而不是将其应用于 DB),为什么还要尝试连接到 DB?是否需要设置一个 JPA 属性来告诉它不要连接到数据库?

任何帮助将不胜感激。

这是堆栈跟踪:

Exception in thread "main" java.lang.UnsupportedOperationException: The application must supply JDBC connections
at org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:61)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator$ConnectionProviderJdbcConnectionAccess.<init>(JpaSchemaGenerator.java:695)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator$ConnectionProviderJdbcConnectionAccess.<init>(JpaSchemaGenerator.java:686)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator.determineAppropriateJdbcConnectionContext(JpaSchemaGenerator.java:413)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator.access$100(JpaSchemaGenerator.java:69)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator$Generation.execute(JpaSchemaGenerator.java:122)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator.performGeneration(JpaSchemaGenerator.java:76)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$3.perform(EntityManagerFactoryBuilderImpl.java:822)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.generateSchema(EntityManagerFactoryBuilderImpl.java:807)
at org.hibernate.jpa.HibernatePersistenceProvider.generateSchema(HibernatePersistenceProvider.java:172)
at org.hibernate.ejb.HibernatePersistence.generateSchema(HibernatePersistence.java:79)
at javax.persistence.Persistence.generateSchema(Persistence.java:87)
at com.cvc.adservice.config.JpaSchemaExport.execute(JpaSchemaExport.java:55)
at com.cvc.adservice.config.JpaSchemaExport.main(JpaSchemaExport.java:26)

这里是persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
     http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

<persistence-unit name="DAI" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <!-- <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> -->
    <properties>

        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
    </properties>
</persistence-unit>

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:

    JPA 实现通常需要一个 Connection 来获取提供可用 JDBC 类型和其他功能的详细信息的 DatabaseMetaData,以便它可以使用所提供的内容来确定要生成的 DDL。无法回答为什么 Hibernate 需要它,但对其他人来说就是这样

    【讨论】:

    • 尼尔,谢谢您的回复。在代码中,它指定了hibernate.dialect=org.hibernate.dialect.Oracle10gDialect。看起来它告诉 JPA 在生成 DDL 时它处理的数据库和版本是重要的。您提到了 JDBC 类型。为什么生成 DDL 很重要?似乎 DDL 应该与 JDBC 类型无关。那么,为什么连接 DB 只是为了生成 DDL?
    • JDBC/SQL 类型对 DDL 很重要,因为在 DDL 中的所有列定义中都指定了 SQL 类型(以及有关此类列的最大长度等信息 - 请查看 DatabaseMetaData)。我不知道 Hibernate 在其“方言”中存储了哪些信息,但是我尝试过的 JPA impls 在内部只有很少的信息(以适应 JDBC 不正确/不完整的地方),并依赖 JDBC 驱动程序说支持什么(否则您必须等到 JPA 提供程序类更新后,当新的 JDBC 驱动程序发布时这些东西才可用)。
    • SQL 类型映射及其大小在“方言”中提供。 Oracle10gDialect 的超类(大部分在 Oracle8iDialect 中)提供了这些映射。示例: registerColumnType( Types.CHAR, "char(1)" );
    猜你喜欢
    • 2015-02-03
    • 2011-01-18
    • 2012-08-23
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多