将旧应用程序从JBoss 5.1.0GA迁移到WildFly 13的过程中。 在以前的服务器上,我们使用的是hibernate3,而在WildFly 13上,我们尝试使用的是hibernate 5。
该应用程序的一点点-它是作为多租户应用程序构建的,因此它具有所有客户端通用的表和特定于客户端的表。这些特定于客户的表带有clientId后缀,因此它们将读取Document_2,Document_3,...,Document_n(例如)。
公用表定义位于hibernate.cfg.xml文件下的.sar档案中。
对于公用表映射,还有另一个类似的类:
@Singleton
@Startup
public class MyHibernateService
implements
DynamicMBean {
private MBeanServer platformMBeanServer;
private ObjectName objectName = null;
@PostConstruct
public void start() {
new Configuration().configure().buildSessionFactory();
this.registerJMX();
}
private void registerJMX() {
try {
this.objectName = new ObjectName("jboss.jca:service=HibernateFactory,name=HibernateFactory");
this.platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
this.platformMBeanServer.registerMBean(this, this.objectName);
} catch (Exception e) {
throw new IllegalStateException("Exception during JMX registration :" + e);
}
}
....
}
此类以JNDI名称绑定公用表的休眠工厂,以便以后可以检索。
客户特定的表定义/映射是从模板派生的。在应用启动时,我们为每个客户端建立特定的会话工厂。我们这样做的方法是解析模板映射,并用特定于客户端的部分替换某些部分。模板将显示为
<class name="com..DocumentMapping" table="TABLENAME">
其中的TABLENAME在启动时将替换为例如Document_2。
执行所有替换的SessionFactoryManager类如下所示:
if (SessionFactoryManager.LOGGER.isDebugEnabled()) {
SessionFactoryManager.LOGGER.info("build custom SessionFactory for datasource: " + databaseConfig);
}
Configuration cfg = new Configuration();
// build all mappings
for (Class c : mappingClasses) {
try {
Method m = c.getMethod("getInstance", (Class[])null);
Helper dao = (Helper)m.invoke(null, (Object[])null);
String tableName = dao.getTableName(id);
String mapping = dao.getMappping();
if (mapping == null) {
throw new DAOException(DAOException.TYPE.SESSION_FACTORY, "Mapping not available from class: " + c.getName());
}
cfg.addXML(mapping);
} catch (Exception e) {
throw new DAOException(DAOException.TYPE.SESSION_FACTORY, e);
}
}
cfg.setProperty("hibernate.dialect", databaseConfig.getDatabaseDialect().getClass().getName());
if (StringTools.isValidString(databaseConfig.getDatabaseJNDI())) {
cfg.setProperty("hibernate.connection.datasource", databaseConfig.getDatabaseJNDI());
} else {
cfg.setProperty("hibernate.connection.url", databaseConfig.getDatabaseURL());
cfg.setProperty("hibernate.connection.driver_class", databaseConfig.getDatabaseDriverClass());
cfg.setProperty("hibernate.connection.username", databaseConfig.getDatabaseUser());
cfg.setProperty("hibernate.connection.password", databaseConfig.getDatabasePassword());
}
if (showSQL) {
cfg.setProperty("hibernate.show_sql", "true");
cfg.setProperty("hibernate.format_sql", "false");
}
if (operation == OPERATION.RECREATE) {
cfg.setProperty("hibernate.hbm2ddl.auto", "update");
} else {
// With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly
// this is necessary in order to remove client tables if something goes wrong at client creation time
cfg.setProperty("hibernate.hbm2ddl.auto", "create-drop");
}
SessionFactory sf = cfg.configure().buildSessionFactory();
System.out.println(cfg.getNamedQueries());
问题是,尽管我不赞成使用cfg.addXML(String xml),但cfg.getNamedQueries()返回一个空映射,就像该映射未加载到配置中一样。
以上所有代码都适用于hibernate3。
我也尝试更改:
SessionFactory sf = cfg.configure().buildSessionFactory();
到
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder();
builder.applySettings(cfg.getProperties());
MetadataSources metaData = new MetadataSources(builder.build());
Metadata buildMetadata = metaData.buildMetadata(builder.build());
SessionFactory sf = buildMetadata.buildSessionFactory();
但无济于事。
我尝试的另一个更改是:
SessionFactory sf = cfg.configure().buildSessionFactory();
即加载映射后,在cfg上调用configure。在这种情况下,我会得到一个重复的查询异常,好像查询不是按会话工厂隔离的。
我使用的休眠版本是5.1.14,默认情况下是WildFly 13附带的版本。
有什么想法吗?
答案 0 :(得分:0)
通过更改
修复cfg.addXML(mapping)
到
cfg.addInputStream(new ByteArrayInputStream(mapping.getBytes()));