Java Spring:AnnotationSessionFactoryBean、Hibernate-Dialect AutoDetection

发布于 2024-08-07 19:18:54 字数 2804 浏览 9 评论 0原文

我使用以下 spring 应用程序上下文:

<!-- Hibernate session factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
      <props>
        <!--
             <prop key="hibernate.dialect">${hibernate.dialect}</prop>
          -->
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            <prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop>

            <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
            <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
            <prop key="hibernate.cache.provider_class">${hibernate.cache.provider}</prop>

            <prop key="hibernate.connection.pool_size">10</prop>
            <prop key="hibernate.jdbc.batch_size">1000</prop>
            <prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>

        </props>
    </property>
    <property name="annotatedClasses">
        <list>
          ...
       </list>
    </property>

    <property name="schemaUpdate" value="${hibernate.schemaUpdate}"/>
</bean>

然后问题是:虽然 Hibernate 应该支持方言自动检测,但该代码不起作用:在 Application-Init 上抛出以下异常:

org.hibernate.HibernateException: The dialect was not set. Set the property hibernate.dialect.
    at org.hibernate.dialect.Dialect.instantiateDialect(Dialect.java:256)
    at org.hibernate.dialect.Dialect.getDialect(Dialect.java:234)
    at org.hibernate.dialect.Dialect.getDialect(Dialect.java:249)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean$3.doInHibernate(LocalSessionFactoryBean.java:957)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.updateDatabaseSchema(LocalSessionFactoryBean.java:953)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.afterSessionFactoryCreation(LocalSessionFactoryBean.java:843)
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:213)

我可以通过以下方式避免此异常:取消注释 hibernate.dialect 属性。为什么我必须这样做?为什么休眠不能像它应该的那样自动检测方言?

我想删除方言属性来解决这个问题。

I use the following spring application context:

<!-- Hibernate session factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
      <props>
        <!--
             <prop key="hibernate.dialect">${hibernate.dialect}</prop>
          -->
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            <prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop>

            <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
            <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
            <prop key="hibernate.cache.provider_class">${hibernate.cache.provider}</prop>

            <prop key="hibernate.connection.pool_size">10</prop>
            <prop key="hibernate.jdbc.batch_size">1000</prop>
            <prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>

        </props>
    </property>
    <property name="annotatedClasses">
        <list>
          ...
       </list>
    </property>

    <property name="schemaUpdate" value="${hibernate.schemaUpdate}"/>
</bean>

Then problem is: Although Hibernate should support Dialect-Autodetection this code doesnt work: Uppon Application-Init the following exception is thrown:

org.hibernate.HibernateException: The dialect was not set. Set the property hibernate.dialect.
    at org.hibernate.dialect.Dialect.instantiateDialect(Dialect.java:256)
    at org.hibernate.dialect.Dialect.getDialect(Dialect.java:234)
    at org.hibernate.dialect.Dialect.getDialect(Dialect.java:249)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean$3.doInHibernate(LocalSessionFactoryBean.java:957)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.updateDatabaseSchema(LocalSessionFactoryBean.java:953)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.afterSessionFactoryCreation(LocalSessionFactoryBean.java:843)
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:213)

I can avoid this exception by uncommenting the hibernate.dialect property. Why do I have to do this? Why cant hibernate just autodetect the dialect like it is supposed to?

I want do remove the dialect-property to solve this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蘑菇王子 2024-08-14 19:18:54

Hibernate 本身尝试Configuration.buildSessioNFactory() 调用期间自动检测方言 - 通常(但并非总是)会成功。

然而,Spring 代码却没有——这就是你得到异常的地方。 LocalSessionFactoryBean.updateDatabaseSchema() 方法使用 Dialect.getDialect() 方法获取需要显式设置方言的 Dialect 实例。

我不太清楚为什么这样做,尽管我怀疑这是为了防止 Hibernate 错误地检测到你的方言并因此弄乱你的数据库(因为更新模式可能会造成相当大的灾难)。

您的选择是:

  1. 显式指定方言
  2. schemaUpdate 设置为 false
  3. 扩展 LocalSessionFactoryBean 并重写 updateDatabaseSchema() 方法以从会话工厂实例中获取(已自动检测到的)方言。

为此,您必须将其类强制转换为 SessionFactoryImplementor:

public void updateDatabaseSchema() throws DataAccessException {
  final Dialect dialect = ((SessionFactoryImplementor) getSessionFactory()).getDialect();
  ...
  hibernateTemplate.execute(new HibernateCallback() {
    ...
    // you already have the dialect so you don't need to get it using this:
    // Dialect dialect = Dialect.getDialect(getConfiguration().getProperties());
    ...
  );
}

Hibernate itself tries to auto-detect dialect during Configuration.buildSessioNFactory() call - and usually, though not always, succeeds.

Spring code, however, does not - and that's where you get the exception. LocalSessionFactoryBean.updateDatabaseSchema() method uses Dialect.getDialect() method to obtain Dialect instance which requires dialect to be explicitly set.

I'm not quite sure why it's done that way, though I suspect it's a precaution against Hibernate mistakenly detecting your dialect incorrectly and messing up your database as a result (since updating schema can potentially be quite disastrous).

Your options are:

  1. Explicitly specifying dialect
  2. Setting schemaUpdate to false
  3. Extending LocalSessionFactoryBean and overriding updateDatabaseSchema() method to take the (already auto-detected) dialect from session factory instance.

You'll have to class cast it to SessionFactoryImplementor for that:

public void updateDatabaseSchema() throws DataAccessException {
  final Dialect dialect = ((SessionFactoryImplementor) getSessionFactory()).getDialect();
  ...
  hibernateTemplate.execute(new HibernateCallback() {
    ...
    // you already have the dialect so you don't need to get it using this:
    // Dialect dialect = Dialect.getDialect(getConfiguration().getProperties());
    ...
  );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文