Hibernate could not fetch the SequenceInformation from the database

前端 未结 4 1483
抹茶落季
抹茶落季 2020-11-30 09:58

I have recently updated hibernate in my application to 5.4.4.Final. And now, I have faced with the following exception during deployment.

ERROR [org.hibernat         


        
相关标签:
4条回答
  • 2020-11-30 10:40

    In the end, I came up to the following solution:

    1. Create a sequence information extractor that extends SequenceInformationExtractorOracleDatabaseImpl:
    public class AppSequenceInformationExtractor extends SequenceInformationExtractorOracleDatabaseImpl 
    {
       /**
        * Singleton access
        */
       public static final AppSequenceInformationExtractor INSTANCE = new AppSequenceInformationExtractor();
       
       @Override
       protected Long resultSetMinValue(ResultSet resultSet) throws SQLException {
          return resultSet.getBigDecimal("min_value").longValue();
       }
    }
    
    1. Create a hibernate dialect that extends Oracle12cDialect:
    public class AppOracleDialect extends Oracle12cDialect
    {
       @Override
       public SequenceInformationExtractor getSequenceInformationExtractor() {
          return AppSequenceInformationExtractor.INSTANCE;
       }
       
       @Override
       public String getQuerySequencesString() {
          return "select * from user_sequences";
       }
    }
    
    1. And then use this dialect in the persistence.xml:
    <property name="hibernate.dialect" value="com.my.app.AppOracleDialect" />
    

    As for the method getQuerySequencesString() overriding and usage USER_SEQUENCES instead of ALL_SEQUENCES it's debatable (See HHH-13322 and HHH-14022). But, in my case, the USER_SEQUENCES usage is preferable.

    0 讨论(0)
  • 2020-11-30 10:45

    I solved the problem as follows. Created an extension for Oracle12cDialect. Limited the maximum/minimum value of columns to SQL

    package ru.mvawork.hibernate;
    
    import org.hibernate.dialect.Oracle12cDialect;
    
    @SuppressWarnings("unused")
    public class CustomOracleDialect extends Oracle12cDialect {
    
        @Override
        public String getQuerySequencesString() {
            return "select SEQUENCE_OWNER, SEQUENCE_NAME, greatest(MIN_VALUE,         -9223372036854775807) MIN_VALUE,\n"+
                    "Least(MAX_VALUE, 9223372036854775808) MAX_VALUE, INCREMENT_BY,     CYCLE_FLAG, ORDER_FLAG, CACHE_SIZE,\n"+
                    "Least(greatest(LAST_NUMBER, -9223372036854775807), 9223372036854775808) LAST_NUMBER,\n"+
                    "PARTITION_COUNT, SESSION_FLAG, KEEP_VALUE\n"+
                    "from all_sequences";
        }
    
    }
    

    In the application.properties file referred to a dialect implementation

    spring.jpa.properties.hibernate.dialect=ru.mvawork.hibernate.CustomOracleDialect
    

    You can recreate sequences by limiting the minimum and maximum values. In my case, I can 't do it. The primary keys that I use have the dimension Number (12), which falls within the range limit from -9223372036854775807 to 9223372036854775808 with a large margin

    0 讨论(0)
  • 2020-11-30 10:54

    add (or Change if already there) the dialect property as below in to "application.properties".

    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect

    0 讨论(0)
  • 2020-11-30 10:58

    You simple used the dafault MAX_VALUE of a sequence, which is too high for the Java LONG datatype.

    Fortunatelly you may any time reset the MAX_VALUE with ALTER SEQUENCE to a lower number that will cause no problems.

    Example

    CREATE SEQUENCE SEQ_TEST START WITH 1 INCREMENT BY 1 NOCYCLE;
    
    
    select MAX_VALUE from ALL_SEQUENCES where SEQUENCE_NAME = 'SEQ_TEST';
    
     MAX_VALUE
    ----------
    9999999999999999999999999999
    
    
    ALTER SEQUENCE SEQ_TEST
      MAXVALUE 9223372036854775807;
    
    select MAX_VALUE from ALL_SEQUENCES where SEQUENCE_NAME = 'SEQ_TEST';
    
     MAX_VALUE
    ----------
    9223372036854775807
    

    and BTW

    it looks strange that hibernate tries to read metadata about all sequences, not only about used in my application.

    Hibernate uses select * from all_sequences as an Oracle Dialect to get the sequence information. Note that ALL_SEQUENCES does not mean all existing sequences, but all sequences, that your Hibernate database user (DBUSER from the connection pool) is granted to use - which is of course absolute correct.

    0 讨论(0)
提交回复
热议问题