HHH-13322 Fix Oracle dialect's 'getQuerySequencesString()' issue by limiting to current schema

This commit is contained in:
Nathan Xu 2020-02-27 10:21:19 -05:00 committed by Andrea Boriero
parent 2bda2d1fd2
commit 188c05cc33
2 changed files with 135 additions and 2 deletions

View File

@ -420,7 +420,7 @@ public class Oracle8iDialect extends Dialect {
else {
return
String.format(
"%s start with %d increment by %d",
"%s start with %d increment by %d",
getCreateSequenceString( sequenceName ),
initialValue,
incrementSize
@ -490,7 +490,7 @@ public class Oracle8iDialect extends Dialect {
@Override
public String getQuerySequencesString() {
return "select * from all_sequences";
return "select * from user_sequences";
}
public SequenceInformationExtractor getSequenceInformationExtractor() {

View File

@ -0,0 +1,133 @@
package org.hibernate.test.dialect.functional;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.id.SequenceMismatchStrategy;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.test.annotations.lob.OracleSeqIdGenDialect;
import org.junit.AfterClass;
import org.junit.Test;
/**
* @author Nathan Xu
*/
@TestForIssue( jiraKey = "HHH-13322" )
@RequiresDialect( Oracle8iDialect.class )
public class OracleExtractSequenceMatadataTest extends BaseCoreFunctionalTestCase {
private static final String SEQUENCE_NAME = SequenceStyleGenerator.DEF_SEQUENCE_NAME;
private static final String SEQUENCE_INCREMENT_SIZE = "50";
private static final String OTHER_SCHEMA_NAME = "C##HHH13322"; // 'C##' is common custom user name prefix in Oracle
private static final String SEQUENCE_INCREMENT_SIZE_FROM_OTHER_SCHEMA = "1";
@Override
protected void configure(Configuration configuration) {
configuration.setProperty( Environment.DIALECT, OracleSeqIdGenDialect.class.getName() );
configuration.setProperty(
AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY,
SequenceMismatchStrategy.EXCEPTION.toString() );
}
@Override
public Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { TestEntity.class };
}
@BeforeClassOnce
public static void setUpDB() throws Exception {
assert ! SEQUENCE_INCREMENT_SIZE.equals( SEQUENCE_INCREMENT_SIZE_FROM_OTHER_SCHEMA );
try ( Connection conn = getConnection() ) {
try ( Statement stmt = conn.createStatement() ) {
try {
stmt.execute( String.format( "DROP USER %s CASCADE", OTHER_SCHEMA_NAME ) );
}
catch ( Exception ignore ) {
}
stmt.execute( String.format( "CREATE USER %s IDENTIFIED BY whatever", OTHER_SCHEMA_NAME ) );
// create identical sequence in other schema with different 'increment size' than specified in id field of the entity
stmt.execute( String.format( "CREATE SEQUENCE %s.%s START WITH 1 INCREMENT BY %s",
OTHER_SCHEMA_NAME,
SEQUENCE_NAME,
SEQUENCE_INCREMENT_SIZE_FROM_OTHER_SCHEMA
) );
// ensure no sequence exists for current schema, so the identical sequence in the other schema could be the only culprit
try {
stmt.execute( String.format(
"DROP SEQUENCE %s",
SEQUENCE_NAME
) );
}
catch ( Exception ignore ) {
}
}
}
}
@Test
public void testHibernateLaunchSuccessfully() {
// if we were lucky to reach here, woa, the sequence from other schema didn't bother us (with different 'increment size's)
}
@AfterClass
public static void tearDownDB() throws SQLException {
try ( Connection conn = getConnection() ) {
try ( Statement stmt = conn.createStatement() ) {
// dropping user with 'cascade' will drop the sequence as well
stmt.execute( String.format( "DROP USER %s CASCADE", OTHER_SCHEMA_NAME ) );
}
catch ( Exception ignore ) {
}
}
}
private static Connection getConnection() throws SQLException {
String url = Environment.getProperties().getProperty( Environment.URL );
String user = Environment.getProperties().getProperty( Environment.USER );
String password = Environment.getProperties().getProperty( Environment.PASS );
return DriverManager.getConnection( url, user, password );
}
@Entity(name = "TestEntity")
public static class TestEntity {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "sequence_generator" )
@GenericGenerator(
name = "sequence_generator",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
@Parameter(name = "sequence_name", value = SEQUENCE_NAME),
@Parameter(name = "initial_value", value = "1" ),
@Parameter(name = "increment_size", value = SEQUENCE_INCREMENT_SIZE),
@Parameter(name = "optimizer", value = "pooled")
}
)
private Long id;
}
}