Search code examples
javahibernateibm-midrange

Hibernate/JPA validation failing when connecting to AS400


I'm developing a Tomcat-based webapp I'm trying to get to talk to an existing AS400 data store. I've copied most of the settings from an existing web app which works, but when I run my new app I get this:

2013-08-08 13:50:11,988 ERROR [RMI TCP Connection(3)-127.0.0.1] org.hibernate.tool.hbm2ddl.SchemaValidator - could not get database metadata
java.sql.SQLException: [SQL5016] Qualified object name SYSSEQUENCES not valid.
    at com.ibm.as400.access.JDError.throwSQLException(JDError.java:646)
    at com.ibm.as400.access.JDError.throwSQLException(JDError.java:617)
    at com.ibm.as400.access.AS400JDBCStatement.commonPrepare(AS400JDBCStatement.java:1578)
    at com.ibm.as400.access.AS400JDBCStatement.executeQuery(AS400JDBCStatement.java:2138)
    at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)
    at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)
    at org.hibernate.tool.hbm2ddl.DatabaseMetadata.initSequences(DatabaseMetadata.java:151)
    at org.hibernate.tool.hbm2ddl.DatabaseMetadata.<init>(DatabaseMetadata.java:69)
    at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:132)
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:378)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1872)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:906)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:288)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
[SNIP]

Seems like it's failing looking for the SYSSEQUENCES object (presumably a table) but there's no such table in my schema, or anywhere that I'm aware of. Why is it doing this and how can I correct it?

Here's the SERVER.XML resource that I'm using to connect:

    <Resource 
        name="jdbc/myresource" 
        auth="Container" 
        driverClassName="com.ibm.as400.access.AS400JDBCDriver" 
        maxActive="20" 
        maxIdle="10" 
        maxWait="5000" 
        password="mypassword" 
        testOnBorrow="true" 
        type="javax.sql.DataSource" 
        url="jdbc:as400://mysystem.mycompany.com;libraries=LIB1 LIB2 LIB3;dateformat=iso;timeformat=iso;prompt=false;naming=system;transaction isolation=none" 
        username="myusername" 
        validationQuery="SELECT * from sysibm/sysdummy1"/>

Here's my PERSISTENCE.XML:

<persistence-unit name="myPersistenceUnit">
    <properties>
        <property name="hibernate.generate_statistics" value="true" />
        <property name="hibernate.cache.use_structured_entries" value="true" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="hibernate.jdbc.batch_size" value="100" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.DB2400Dialect" />
        <property name="hibernate.hbm2ddl.auto" value="validate"  />
    </properties>
</persistence-unit>

Solution

  • Examining the stack trace the issue begins at org.hibernate.tool.hbm2ddl.DatabaseMetadata.initSequences.

    The initSequences method checks the dialect for sequence support:

    DatabaseMetadata.initSequences

    private void initSequences(Connection connection, Dialect dialect) throws SQLException {
        if ( dialect.supportsSequences() ) {
            String sql = dialect.getQuerySequencesString();
    

    DB2400Dialect reports that it does not:

    DB2400Dialect.java

    public class DB2400Dialect extends DB2Dialect {
        @Override
        public boolean supportsSequences() {
            return false;
        }
    

    For reference the base DB2Dialect does support sequences and references sysibm.syssequences:

    DB2Dialect.java  

    @Override
    public boolean supportsSequences() {
        return true;
    }
    
    @Override
    public String getQuerySequencesString() {
        return "select seqname from sysibm.syssequences";
    }
    

    It would appear that either your dialect is not being set properly or your version of DB2400Dialect is reporting that it does support sequences.