代码之家  ›  专栏  ›  技术社区  ›  theomega

Java Spring:注释StaseCasePosieBe,Hibernate方言自动检测

  •  2
  • theomega  · 技术社区  · 15 年前

    我使用以下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应该支持方言自动检测,但此代码不起作用: upon 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属性的注释来避免此异常。我为什么要这么做?为什么冬眠不能像应该的那样自动检测方言?

    我要删除方言属性以解决 this 问题。

    1 回复  |  直到 10 年前
        1
  •  6
  •   ChssPly76    15 年前

    冬眠本身 尝试 自动检测方言 Configuration.buildSessioNFactory() 打电话-通常,尽管不总是成功。

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

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

    您的选择是:

    1. 显式指定方言
    2. 设置 schemaUpdate
    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());
        ...
      );
    }