Skip to content

Commit

Permalink
HHH-13229 - Sequences in MariaDB doesnt work on existing sequence
Browse files Browse the repository at this point in the history
  • Loading branch information
vladmihalcea committed Jan 31, 2019
1 parent 0750716 commit d158762
Show file tree
Hide file tree
Showing 6 changed files with 373 additions and 14 deletions.
2 changes: 1 addition & 1 deletion gradle/databases.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ ext {
'jdbc.url' : 'jdbc:mysql://127.0.0.1/hibernate_orm_test?useSSL=false'
],
mariadb : [
'db.dialect' : 'org.hibernate.dialect.MariaDB102Dialect',
'db.dialect' : 'org.hibernate.dialect.MariaDB103Dialect',
'jdbc.driver': 'org.mariadb.jdbc.Driver',
'jdbc.user' : 'hibernate_orm_test',
'jdbc.pass' : 'hibernate_orm_test',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
*/
package org.hibernate.dialect;


import org.hibernate.LockOptions;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorMariaDBDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;

Expand Down Expand Up @@ -63,8 +62,7 @@ public String getQuerySequencesString() {

@Override
public SequenceInformationExtractor getSequenceInformationExtractor() {
//TODO: Future improvement - https://hibernate.atlassian.net/browse/HHH-13008
return SequenceNameExtractorImpl.INSTANCE;
return SequenceInformationExtractorMariaDBDatabaseImpl.INSTANCE;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.hibernate.id.enhanced;

import java.io.Serializable;
import java.util.Objects;
import java.util.Properties;

import org.hibernate.HibernateException;
Expand Down Expand Up @@ -568,14 +569,20 @@ public void registerExportables(Database database) {
* @return sequence increment value
*/
private Long getSequenceIncrementValue(JdbcEnvironment jdbcEnvironment, String sequenceName) {
return jdbcEnvironment.getExtractedDatabaseMetaData().getSequenceInformationList().stream().filter(
sequenceInformation -> {
Identifier catalog = sequenceInformation.getSequenceName().getCatalogName();
Identifier schema = sequenceInformation.getSequenceName().getSchemaName();
return sequenceName.equalsIgnoreCase( sequenceInformation.getSequenceName().getSequenceName().getText() ) &&
( catalog == null || catalog.equals( jdbcEnvironment.getCurrentCatalog() ) ) &&
( schema == null || schema.equals( jdbcEnvironment.getCurrentSchema() ) );
}
).map( SequenceInformation::getIncrementValue ).findFirst().orElse( null );
return jdbcEnvironment.getExtractedDatabaseMetaData().getSequenceInformationList()
.stream()
.filter(
sequenceInformation -> {
Identifier catalog = sequenceInformation.getSequenceName().getCatalogName();
Identifier schema = sequenceInformation.getSequenceName().getSchemaName();
return sequenceName.equalsIgnoreCase( sequenceInformation.getSequenceName().getSequenceName().getText() ) &&
( catalog == null || catalog.equals( jdbcEnvironment.getCurrentCatalog() ) ) &&
( schema == null || schema.equals( jdbcEnvironment.getCurrentSchema() ) );
}
)
.map( SequenceInformation::getIncrementValue )
.filter( Objects::nonNull )
.findFirst()
.orElse( null );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.tool.schema.extract.internal;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.boot.model.relational.QualifiedSequenceName;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;

/**
* @author Vlad Mihalcea, Magnus Hagström
*/
public class SequenceInformationExtractorMariaDBDatabaseImpl extends SequenceInformationExtractorLegacyImpl {
/**
* Singleton access
*/
public static final SequenceInformationExtractorMariaDBDatabaseImpl INSTANCE = new SequenceInformationExtractorMariaDBDatabaseImpl();

// SQL to get metadata from individual sequence
private static final String SQL_SEQUENCE_QUERY =
"SELECT '%1$s' as sequence_name, minimum_value, maximum_value, start_value, increment, cache_size FROM %1$s ";

private static final String UNION_ALL =
"UNION ALL ";

@Override
public Iterable<SequenceInformation> extractMetadata(ExtractionContext extractionContext) throws SQLException {
final String lookupSql = extractionContext.getJdbcEnvironment().getDialect().getQuerySequencesString();

// *should* never happen, but to be safe in the interest of performance...
if (lookupSql == null) {
return SequenceInformationExtractorNoOpImpl.INSTANCE.extractMetadata(extractionContext);
}

final IdentifierHelper identifierHelper = extractionContext.getJdbcEnvironment().getIdentifierHelper();

final List<SequenceInformation> sequenceInformationList = new ArrayList<>();
final List<String> sequenceNames = new ArrayList<>();

try (
final Statement statement = extractionContext.getJdbcConnection().createStatement();
final ResultSet resultSet = statement.executeQuery( lookupSql );
) {
while ( resultSet.next() ) {
sequenceNames.add( resultSetSequenceName( resultSet ) );
}
}

if ( !sequenceNames.isEmpty() ) {
StringBuilder sequenceInfoQueryBuilder = new StringBuilder();

for ( String sequenceName : sequenceNames ) {
if ( sequenceInfoQueryBuilder.length() > 0 ) {
sequenceInfoQueryBuilder.append( UNION_ALL );
}
sequenceInfoQueryBuilder.append( String.format( SQL_SEQUENCE_QUERY, sequenceName ) );
}

int index = 0;

try (
final Statement statement = extractionContext.getJdbcConnection().createStatement();
final ResultSet resultSet = statement.executeQuery( sequenceInfoQueryBuilder.toString() );
) {

while ( resultSet.next() ) {

SequenceInformation sequenceInformation = new SequenceInformationImpl(
new QualifiedSequenceName(
null,
null,
identifierHelper.toIdentifier(
resultSetSequenceName(resultSet)
)
),
resultSetStartValueSize(resultSet),
resultSetMinValue(resultSet),
resultSetMaxValue(resultSet),
resultSetIncrementValue(resultSet)
);

sequenceInformationList.add(sequenceInformation);
}

}
}

return sequenceInformationList;
}

protected String resultSetSequenceName(ResultSet resultSet) throws SQLException {
return resultSet.getString(1);
}

@Override
protected String sequenceCatalogColumn() {
return null;
}

@Override
protected String sequenceSchemaColumn() {
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.MariaDB103Dialect;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.SQLServer2012Dialect;
import org.hibernate.engine.spi.SessionImplementor;
Expand Down Expand Up @@ -54,6 +55,10 @@ else if ( dialect instanceof AbstractHANADialect ) {

queryString = "select " + sequenceName + ".currval from sys.dummy";
}
else if ( dialect instanceof MariaDB103Dialect ) {

queryString = "select LASTVAL(" + sequenceName + ")";
}
else {
queryString = "select currval('" + sequenceName + "');";
}
Expand Down
Loading

0 comments on commit d158762

Please sign in to comment.