Support for Java Hibernate 5

Working on implementation FHIR to my project, I found interesting project HAPI-FHIR, which could help me to quickly launch my FHIR api server with InterSystems Caché as a storage, because this projects uses Hibernate to connect to database, as an example they use DerbyDB. I tried to change settings to use InterSystems Caché, but unfortunately it does not work and throw some errors inside HIbernate. As I found in Caché documentation, I have not some many options, I just have to set Cache dialect, and set database url.  This projects uses Hibernate 5.1

Error which I get: DROP not supported as a after-use action for global temp table strategy

Maybe somebody faced this error too, and knows how to solve it ?

Answers

We came across the same issue earlier this year. Our tack was similar though the details differ, in particular which bulkstrategy was used. We just changed the AfterUseAction to Clean and kept the basic strategy. Why did you choose to change the strategy to LocalTemporaryTableBulkIdStrategy​.

public class Cache71DialectAltered extends Cache71Dialect {
    @Override
    public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
        return new GlobalTemporaryTableBulkIdStrategy(new IdTableSupportStandardImpl() {
            @Override
            public String generateIdTableName(String baseName) {
                final String name = super.generateIdTableName(baseName);
                return name.length() > 25 ? name.substring(1, 25) : name;
            }

            @Override
            public String getCreateIdTableCommand() {
                return "create global temporary table";
            }
        }, AfterUseAction.CLEAN);
    }
}

I'm just looked at another examples in other dialects. I'm not so good in Java yet, and even in Hibernate, and not sure that my way is correct.

I've been meaning to ask the Intersystems people what their thoughts are, after all in some press releases they make a big deal about the hibernate dialect even though it's so old. 

I don't think knowing the proper way of doing it is possible without in depth knowledge of both hibernate and cache, something I'm not sure anyone has, but this works for us. 

We are in the process of updating our Hibernate dialect and plan to push the new dialect to the repository later this year. I got word from our developers that we are using the same strategy as Nicholas provided in his getDefaultMultiTableBulkIdStrategy implementation.

I'm glad to hear that I was on the right track. I look forward to the updated dialect.

I wanted to point out one other thing. We are also using the Hibernate Reverse Engineering tool. We came across some issues in Cache involving foreign keys and meta data, in particular the default generated keys weren't unique and there were issues with exported keys being removed in the meta data(Tables B and C have a foreign keys to Table A. Table B get recompiled then exported keys from Table A to Tables B and C might get deleted). This caused the hibernate tool reverse engineering to not work. We were able to get around these issues with some hacks in the code where we repair the meta data, but we wanted to let you know there were issues. 

If you want more information, I assume you have my email on file.

The problem still seems to exist in Hibernate 5.3.2.

What's the performance like?

I've been using HAPI FHIR Server alongside Healthshare for several months in eval/test environments but not tried Cache as the database.

I'm just in the begin, I'm working on developing FHIR-based application, and currently it's enough, mostly because so far for production.  

Comments

I managed to work it, I've just extended Cache dialect for Hibernate, and changed GlobalTemporary table which is not support DROP to LocalTemporaryTable. And changed column type for boolean, for supported in Caché data type bit. And looks like, I get working FHIR server which stores all data in Caché.

public class CacheDialect extends Cache71Dialect {

    public CacheDialect() {
        super();
        this.registerColumnType(Types.BOOLEAN, "bit");
    }

    @Override
    public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
        return new LocalTemporaryTableBulkIdStrategy(
            new IdTableSupportStandardImpl() {
                @Override
                public String generateIdTableName(String baseName) {
                    final String name = super.generateIdTableName( baseName );
                    return name.length() > 25 ? name.substring( 1, 25 ) : name;
                }

                @Override
                public String getCreateIdTableCommand() {
                    return "create global temporary table";
                }
            },
            AfterUseAction.DROP,
            null
        );

    }

}

If anybody interesting in it. I've published repository with working example of HAPI-FHIR server which is working with Caché.

Just noticed, that some time, my HAPI-FHIR server which connected to Ensemble, responses too long on some queries. And found that on Ensemble side, too many lock, and looks looks some of them in a dead-lock, and not sure why is happens yet.