我将使用序列的实体插入MSSQL 2014数据库时遇到问题。我使用Wildfly 10 CR4随附的hibernate模式(但是在CR1和CR2中,我遇到了相同的问题)。
以下是有关Webapp运行环境的一般信息:
我的persistence.xml文件如下所示:
<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>
现在,当我遇到错误时会发生什么。
首先,当启动Wildfly时,我会看到以下警告:
警告[org.hibernate.engine.jdbc.dialect.internal.StandardDialectResolver](ServerService线程池-68)HHH000385:使用SQL Server 2000方言的未知Microsoft SQL Server主版本[12]
我在网上浏览后发现,此问题自2015年1月起就已为人所知,但不幸的是,这仍然是一个未解决的问题。
当我尝试保留ID配置为使用序列的新实体时,会引发错误本身:
@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;
引发的异常如下:
com.microsoft.sqlserver.jdbc.SQLServerException:无效的对象名称“ SEQ_MAP_BOOKMARKS”。
这并不奇怪,因为hibernate使用的是错误的方言-一种对序列一无所知的方言。
当我修改persistence.xml并添加以下行时:
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2012Dialect"/>
一切都像魅力。
问题在于该应用程序还将与另一台服务器上的Oracle数据库以及另一台服务器上的Postgres一起使用。我想避免必须准备同一应用程序的多个版本。
有人知道解决这个问题的办法吗?还是应该等待其他Wildfly和/或hibernate版本出现?
同时团队无法解决此问题,您可以创建一个自定义的方言解析器:
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; } }
然后,在持久性单元中进行配置:
<property name="hibernate.dialect_resolvers" value="com.oki.scope.hibernate.ScopeStandardDialectResolver" />
基于此示例:http : //blog.exxeta.com/2016/03/23/dynamically-resolve- hibernate-database-dialect/