错误的冬眠方言MSSQL 2014 [英] Wrong hibernate dialect for MSSQL 2014

查看:285
本文介绍了错误的冬眠方言MSSQL 2014的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个将使用序列的实体插入MSSQL 2014数据库的问题。我使用Wildfly 10 CR4附带的hibernate(但在CR1和CR2中,我遇到了同样的问题)。



以下是关于webapp运行环境的一般信息: / p>


  1. Wildfly 10(CR4)
  2. Java 8 u 51

  3. Windows 7 Proffesional 64位

  4. MSSQL Server 2014

  5. MSSQL驱动程序:在应用程序服务器上部署sqljdbc42.jar

我的persistence.xml文件如下所示:

 < ; persistence-unit name =mb_managed_putransaction-type =JTA> 
< provider> org.hibernate.jpa.HibernatePersistenceProvider< / provider>
< jta-data-source> java:/ jdbc / datasource< / jta-data-source>
<属性>
< property name =hibernate.archive.autodetectionvalue =class,hbm/>
< property name =hibernate.show_sqlvalue =true/>
< property name =hibernate.format_sqlvalue =true/>
< property name =hibernate.jdbc.batch_sizevalue =0/>
< property name =hibernate.default_schema_value =openmap/>
< property name =hibernate.connection.useUnicodevalue =yes/>
< property name =hibernate.connection.characterEncodingvalue =UTF-8/>
< / properties>
< / persistence-unit>

现在,我遇到错误时会发生什么。



首先,当Wildfly开始时,我可以看到这个警告:

WARN [org.hibernate.engine.jdbc.dialect.internal .StandardDialectResolver](ServerService线程池 - 68)HHH000385:未知Microsoft SQL Server主要版本[12]使用SQL Server 2000方言



并且发现自2015年1月以来就已经知道这个问题,但不幸的是,它仍然是一个未解决的问题 a>。



当我试图持久保存一个配置了ID的新实体时,错误本身就会出现:

  @Id 
@Column(name =MAP_BOOKMARK_ID)
@SequenceGenerator(name =SEQ_MAP_BOOKMARKS,sequenceName =SEQ_MAP_BOOKMARKS,allocationSize = 1)
@GeneratedValue(generator =SEQ_MAP_BOOKMARKS,strategy = Generati onType.SEQUENCE)
私人长ID;

引发的异常如下:

com.microsoft.sqlserver.jdbc.SQLServerException:无效的对象名称SEQ_MAP_BOOKMARKS。

这并不令人意外,因为hibernate使用错误的方言 - 对序列一无所知的人。



当我修改persistence.xml并添加以下行时:

 < property name =hibernate.dialectvalue =org.hibernate.dialect.SQLServer2012Dialect/> 

一切都像一个魅力。



问题在于应用程序也可以在另一台服务器上使用Oracle数据库,在另一台服务器上使用Postgres。我想避免必须准备同一个应用程序的多个版本。



有人知道这个问题的解决方案吗?或者我应该等待另一个Wildfly和/或hibernate版本出现?

解决方案

与此同时,团队没有解决这个问题,可以创建一个自定义的方言解析器:

  public class ScopeStandardDialectResolver implements DialectResolver {


private static final long serialVersionUID = 1L;

@Override
public方言resolveDialect(DialectResolutionInfo info){
方言customDialectResolver = customDialectResolver(info);
Log.getInstance()。logInfo(Thread.currentThread()。getStackTrace(),customDialectResolver.getClass()。getName());
返回customDialectResolver;
}

private方言customDialectResolver(DialectResolutionInfo info){
final String databaseName = info.getDatabaseName();
final int majorVersion = info.getDatabaseMajorVersion();
if(isSqlServer2014(databaseName,majorVersion)){
return new SQLServer2012Dialect();
} else {
return StandardDialectResolver.INSTANCE.resolveDialect(info);


$ b $ private bool isSqlServer2014(final String databaseName,final int majorVersion){
return databaseName.startsWith(Microsoft SQL Server)&& majorVersion == 12;
}

}

然后在持久性单元中进行配置:

 < property name =hibernate.dialect_resolversvalue =com.oki.scope.hibernate.ScopeStandardDialectResolver/> ; 

在此示例中: http://blog.exxeta.com/2016/03/23/dynamically-resolve-hibernate-database-dialect/ < a>


I have a problem with inserting entities, that use sequences, to a MSSQL 2014 database. I use hibernate that is shipped with Wildfly 10 CR4 (but in CR1 and CR2 I got the same issue).

Here is a general info on the webapp run environment:

  1. Wildfly 10 (CR4)
  2. Java 8 u 51
  3. Windows 7 Proffesional 64bit
  4. MSSQL Server 2014
  5. MSSQL driver: sqljdbc42.jar is deployed on the application server

My persistence.xml file looks like this:

<persistence-unit name="mb_managed_pu" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>java:/jdbc/datasource</jta-data-source>
    <properties>
        <property name="hibernate.archive.autodetection" value="class, hbm" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="hibernate.jdbc.batch_size" value="0" />
        <property name="hibernate.default_schema_" value="openmap"/>
        <property name="hibernate.connection.useUnicode" value="yes"/>
        <property name="hibernate.connection.characterEncoding" value="UTF-8"/>
    </properties>
</persistence-unit>

Now here is what happens when I run into an error.

First, when Wildfly is started, I can see this warning:

WARN [org.hibernate.engine.jdbc.dialect.internal.StandardDialectResolver] (ServerService Thread Pool -- 68) HHH000385: Unknown Microsoft SQL Server major version [12] using SQL Server 2000 dialect

I looked through the web and found that this problem is already known since January 2015, but unfortunately it is still an open issue.

The error itself is raised when I try to persist a new entity that has the ID configured to use sequences:

@Id
@Column(name = "MAP_BOOKMARK_ID")
@SequenceGenerator(name = "SEQ_MAP_BOOKMARKS", sequenceName = "SEQ_MAP_BOOKMARKS", allocationSize = 1)
@GeneratedValue(generator = "SEQ_MAP_BOOKMARKS", strategy = GenerationType.SEQUENCE)
private long                    id;

The exception raised is as follows:

com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name „SEQ_MAP_BOOKMARKS".

This is not a surprise since hibernate is using the wrong dialect - the one that does not know anything about sequences.

When I modify persistence.xml and add this line:

<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2012Dialect"/>

everything works like a charm.

The problem is that the application will also work with Oracle database on another server and on Postgres on another. I'd like to avoid having to prepare multiple versions of the same application.

Does anybody know of a solution to this problem ? Or should I wait for another Wildfly and/or hibernate version to appear ?

解决方案

Meanwhile the team does not solve this problem, you can create a custom dialect resolver:

public class ScopeStandardDialectResolver implements DialectResolver {


private static final long serialVersionUID = 1L;

    @Override
    public Dialect resolveDialect(DialectResolutionInfo info) {
        Dialect customDialectResolver = customDialectResolver(info);
        Log.getInstance().logInfo(Thread.currentThread().getStackTrace(), customDialectResolver.getClass().getName());
        return customDialectResolver;
    }

    private Dialect customDialectResolver(DialectResolutionInfo info) {
        final String databaseName = info.getDatabaseName();
        final int majorVersion = info.getDatabaseMajorVersion();
        if (isSqlServer2014(databaseName, majorVersion)) {
            return new SQLServer2012Dialect(); 
        } else {
            return StandardDialectResolver.INSTANCE.resolveDialect(info);
        }
    }

    private boolean isSqlServer2014(final String databaseName, final int majorVersion) {
        return databaseName.startsWith("Microsoft SQL Server") && majorVersion == 12;
    }

}

Then you configure in your persistence unit:

<property name="hibernate.dialect_resolvers" value="com.oki.scope.hibernate.ScopeStandardDialectResolver" />

Based in this example: http://blog.exxeta.com/2016/03/23/dynamically-resolve-hibernate-database-dialect/

这篇关于错误的冬眠方言MSSQL 2014的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆