Mar*_*ski 6 java hibernate wildfly
我将使用序列的实体插入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>
Run Code Online (Sandbox Code Playgroud)
现在这是我遇到错误时会发生什么.
首先,当Wildfly启动时,我可以看到这个警告:
WARN [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;
Run Code Online (Sandbox Code Playgroud)
提出的例外情况如下:
com.microsoft.sqlserver.jdbc.SQLServerException:无效的对象名称"SEQ_MAP_BOOKMARKS".
这并不奇怪,因为hibernate使用了错误的方言 - 对序列一无所知的方言.
当我修改persistence.xml并添加以下行时:
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2012Dialect"/>
Run Code Online (Sandbox Code Playgroud)
一切都像一个魅力.
问题是该应用程序还可以在另一台服务器上使用Oracle数据库,在另一台服务器上使用Postgres.我想避免必须准备同一个应用程序的多个版本.
有人知道这个问题的解决方案吗?或者我应该等待另一个Wildfly和/或休眠版本出现?
小智 5
同时团队没有解决这个问题,你可以创建一个自定义方言解析器:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在持久性单元中进行配置:
<property name="hibernate.dialect_resolvers" value="com.oki.scope.hibernate.ScopeStandardDialectResolver" />
Run Code Online (Sandbox Code Playgroud)
基于此示例:http://blog.exxeta.com/2016/03/23/dynamically-resolve-hibernate-database-dialect/