Skip to content

Commit ecc3334

Browse files
committed
extend the synchronizer to also work for table generators
1 parent 3347feb commit ecc3334

14 files changed

+301
-176
lines changed

hibernate-core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ default void configure(Optimizer optimizer) {
9797
* @param table The table for which this structure is used to generate values
9898
* @param optimizer The {@link Optimizer} for this generator
9999
*
100-
* @see org.hibernate.relational.SchemaManager#resynchronizeSequences()
100+
* @see org.hibernate.relational.SchemaManager#resynchronizeGenerators()
101101
*
102102
* @since 7.2
103103
*/
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.id.enhanced;
6+
7+
import org.hibernate.HibernateException;
8+
import org.hibernate.dialect.Dialect;
9+
10+
import java.sql.Connection;
11+
import java.sql.PreparedStatement;
12+
import java.sql.SQLException;
13+
14+
/**
15+
* @author Gavin King
16+
*/
17+
class ResyncHelper {
18+
19+
// TODO: Use SqlExceptionHelper, SqlStatementLogger, available in the JdbcContext
20+
21+
private static long resultValue(PreparedStatement select) throws SQLException {
22+
try ( var resultSet = select.executeQuery() ) {
23+
resultSet.next();
24+
return resultSet.getLong( 1 );
25+
}
26+
}
27+
28+
static long getNextSequenceValue(Connection connection, String sequenceName, Dialect dialect) {
29+
final String sequenceCurrentValue =
30+
dialect.getSequenceSupport()
31+
.getSequenceNextValString( sequenceName );
32+
try ( var select = connection.prepareStatement( sequenceCurrentValue ) ) {
33+
return resultValue( select );
34+
}
35+
catch (SQLException e) {
36+
throw new HibernateException( "Could not fetch the current sequence value from the database", e );
37+
}
38+
}
39+
40+
static long getMaxPrimaryKey(Connection connection, String primaryKeyColumnName, String tableName) {
41+
final String selectMax =
42+
"select max(" + primaryKeyColumnName + ") from " + tableName;
43+
try ( var select = connection.prepareStatement( selectMax ) ) {
44+
return resultValue( select );
45+
}
46+
catch (SQLException e) {
47+
throw new HibernateException( "Could not fetch the max primary key from the database", e );
48+
}
49+
}
50+
51+
static long getCurrentTableValue(Connection connection, String tableName, String columnName) {
52+
final String selectCurrent =
53+
"select " + columnName + " from " + tableName;
54+
try ( var select = connection.prepareStatement( selectCurrent ) ) {
55+
return resultValue( select );
56+
}
57+
catch (SQLException e) {
58+
throw new HibernateException( "Could not fetch the current table value from the database", e );
59+
}
60+
}
61+
62+
static long getCurrentTableValue(
63+
Connection connection, String tableName, String columnName,
64+
String segmentColumnName, String segmentValue) {
65+
final String selectCurrent =
66+
"select " + columnName + " from " + tableName
67+
+ " where " + segmentColumnName + " = '" + segmentValue + "'";
68+
try ( var select = connection.prepareStatement( selectCurrent ) ) {
69+
return resultValue( select );
70+
}
71+
catch (SQLException e) {
72+
throw new HibernateException( "Could not fetch the current table value from the database", e );
73+
}
74+
}
75+
}

hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,22 @@
44
*/
55
package org.hibernate.id.enhanced;
66

7-
import java.sql.Connection;
87
import java.sql.SQLException;
98

109
import org.hibernate.AssertionFailure;
11-
import org.hibernate.HibernateException;
1210
import org.hibernate.boot.model.relational.Database;
1311
import org.hibernate.boot.model.relational.InitCommand;
1412
import org.hibernate.boot.model.relational.QualifiedName;
1513
import org.hibernate.boot.model.relational.Sequence;
1614
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
17-
import org.hibernate.dialect.Dialect;
1815
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1916
import org.hibernate.id.IntegralDataTypeHolder;
2017
import org.hibernate.mapping.Table;
2118

2219
import static org.hibernate.engine.jdbc.JdbcLogging.JDBC_LOGGER;
2320
import static org.hibernate.id.IdentifierGeneratorHelper.getIntegralDataTypeHolder;
21+
import static org.hibernate.id.enhanced.ResyncHelper.getNextSequenceValue;
22+
import static org.hibernate.id.enhanced.ResyncHelper.getMaxPrimaryKey;
2423

2524
/**
2625
* Describes a sequence.
@@ -176,44 +175,14 @@ public void registerExtraExportables(Table table, Optimizer optimizer) {
176175
final String tableName = context.format( table.getQualifiedTableName() );
177176
final String primaryKeyColumnName = table.getPrimaryKey().getColumn( 0 ).getName();
178177
final int adjustment = optimizer.getAdjustment();
179-
final long max = getMax( connection, primaryKeyColumnName, tableName );
180-
final long current = getCurrent( connection, sequenceName, context.getDialect() );
178+
final long max = getMaxPrimaryKey( connection, primaryKeyColumnName, tableName );
179+
final long current = getNextSequenceValue( connection, sequenceName, context.getDialect() );
181180
final long newValue = Math.max( max + adjustment, current );
182181
final String restart = "alter sequence " + sequenceName + " restart with " + newValue;
183182
return new InitCommand( restart );
184183
} );
185184
}
186185

187-
188-
private long getCurrent(Connection connection, String sequenceName, Dialect dialect) {
189-
final String sequenceCurrentValue =
190-
dialect.getSequenceSupport()
191-
.getSequenceNextValString( sequenceName );
192-
try ( var select = connection.prepareStatement( sequenceCurrentValue ) ) {
193-
try ( var resultSet = select.executeQuery() ) {
194-
resultSet.next();
195-
return resultSet.getLong(1);
196-
}
197-
}
198-
catch (SQLException e) {
199-
throw new HibernateException( "Could not fetch the current sequence value from the database", e );
200-
}
201-
}
202-
203-
private static long getMax(Connection connection, String primaryKeyColumnName, String tableName) {
204-
final String selectMax =
205-
"select max(" + primaryKeyColumnName + ") from " + tableName;
206-
try ( var select = connection.prepareStatement( selectMax ) ) {
207-
try ( var resultSet = select.executeQuery() ) {
208-
resultSet.next();
209-
return resultSet.getLong(1);
210-
}
211-
}
212-
catch (SQLException e) {
213-
throw new HibernateException( "Could not fetch the max primary key from the database", e );
214-
}
215-
}
216-
217186
@Override
218187
public boolean isPhysicalSequence() {
219188
return true;

0 commit comments

Comments
 (0)