Hibernate 5-以编程方式向配置添加hbm映射-未找到命名查询

时间:2018-06-20 09:39:47

标签: java hibernate wildfly hibernate-mapping hibernate-5.x

将旧应用程序从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附带的版本。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

通过更改

修复
cfg.addXML(mapping)

cfg.addInputStream(new ByteArrayInputStream(mapping.getBytes()));