Skip to content

Commit 3c806ab

Browse files
committed
simplify ResultSetAccess hierarchy
1 parent c38ab8b commit 3c806ab

File tree

4 files changed

+125
-152
lines changed

4 files changed

+125
-152
lines changed

hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/AbstractResultSetAccess.java

Lines changed: 107 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,53 @@
77
import java.sql.ResultSetMetaData;
88
import java.sql.SQLException;
99

10+
import jakarta.persistence.EnumType;
1011
import org.hibernate.dialect.Dialect;
12+
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
13+
import org.hibernate.engine.spi.SessionFactoryImplementor;
1114
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1215
import org.hibernate.internal.util.StringHelper;
16+
import org.hibernate.type.BasicType;
17+
import org.hibernate.type.descriptor.java.JavaType;
18+
import org.hibernate.type.descriptor.jdbc.JdbcType;
19+
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
20+
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
21+
import org.hibernate.type.spi.TypeConfiguration;
1322

1423
/**
24+
* Base implementation of {@link ResultSetAccess}.
25+
*
1526
* @author Steve Ebersole
1627
*/
1728
public abstract class AbstractResultSetAccess implements ResultSetAccess {
1829
private final SharedSessionContractImplementor persistenceContext;
19-
private final Dialect dialect;
2030
private ResultSetMetaData resultSetMetaData;
2131

2232
public AbstractResultSetAccess(SharedSessionContractImplementor persistenceContext) {
2333
this.persistenceContext = persistenceContext;
24-
this.dialect = persistenceContext.getJdbcServices().getDialect();
2534
}
2635

36+
protected abstract SessionFactoryImplementor getFactory();
37+
2738
protected SharedSessionContractImplementor getPersistenceContext() {
2839
return persistenceContext;
2940
}
3041

31-
protected ResultSetMetaData getMetaData() {
42+
private SqlExceptionHelper getSqlExceptionHelper() {
43+
return getFactory().getJdbcServices().getSqlExceptionHelper();
44+
}
45+
46+
private Dialect getDialect() {
47+
return getFactory().getJdbcServices().getDialect();
48+
}
49+
50+
private ResultSetMetaData getResultSetMetaData() {
3251
if ( resultSetMetaData == null ) {
3352
try {
3453
resultSetMetaData = getResultSet().getMetaData();
3554
}
3655
catch (SQLException e) {
37-
throw persistenceContext.getJdbcServices().getSqlExceptionHelper()
56+
throw getSqlExceptionHelper()
3857
.convert( e, "Unable to access ResultSetMetaData" );
3958
}
4059
}
@@ -45,37 +64,111 @@ protected ResultSetMetaData getMetaData() {
4564
@Override
4665
public int getColumnCount() {
4766
try {
48-
return getMetaData().getColumnCount();
67+
return getResultSetMetaData().getColumnCount();
4968
}
5069
catch (SQLException e) {
51-
throw getFactory().getJdbcServices().getJdbcEnvironment().getSqlExceptionHelper()
70+
throw getSqlExceptionHelper()
5271
.convert( e, "Unable to access ResultSet column count" );
5372
}
5473
}
5574

5675
@Override
5776
public int resolveColumnPosition(String columnName) {
5877
try {
59-
return getResultSet().findColumn(
60-
StringHelper.unquote( columnName, this.dialect )
61-
);
78+
return getResultSet()
79+
.findColumn( StringHelper.unquote( columnName, getDialect() ) );
6280
}
6381
catch (SQLException e) {
64-
throw getFactory().getJdbcServices().getJdbcEnvironment().getSqlExceptionHelper()
82+
throw getSqlExceptionHelper()
6583
.convert( e, "Unable to find column position by name: " + columnName );
6684
}
6785
}
6886

6987
@Override
7088
public String resolveColumnName(int position) {
7189
try {
72-
return dialect
73-
.getColumnAliasExtractor()
74-
.extractColumnAlias( getMetaData(), position );
90+
return getDialect().getColumnAliasExtractor()
91+
.extractColumnAlias( getResultSetMetaData(), position );
7592
}
7693
catch (SQLException e) {
77-
throw getFactory().getJdbcServices().getJdbcEnvironment().getSqlExceptionHelper()
94+
throw getSqlExceptionHelper()
7895
.convert( e, "Unable to find column name by position" );
7996
}
8097
}
98+
99+
@Override
100+
public int getResultCountEstimate() {
101+
return -1;
102+
}
103+
104+
@Override
105+
public <J> BasicType<J> resolveType(int position, JavaType<J> explicitJavaType, TypeConfiguration typeConfiguration) {
106+
try {
107+
final ResultSetMetaData metaData = getResultSetMetaData();
108+
final JdbcTypeRegistry registry = typeConfiguration.getJdbcTypeRegistry();
109+
final String columnTypeName = metaData.getColumnTypeName( position );
110+
final int columnType = metaData.getColumnType( position );
111+
final int scale = metaData.getScale( position );
112+
final int precision = metaData.getPrecision( position );
113+
final int displaySize = metaData.getColumnDisplaySize( position );
114+
final Dialect dialect = getDialect();
115+
final int length = dialect.resolveSqlTypeLength( columnTypeName, columnType, precision, scale, displaySize );
116+
final JdbcType resolvedJdbcType =
117+
dialect.resolveSqlTypeDescriptor( columnTypeName, columnType, length, scale, registry );
118+
final JdbcType jdbcType =
119+
explicitJavaType == null
120+
? resolvedJdbcType
121+
: jdbcType( explicitJavaType, resolvedJdbcType, length, precision, scale, typeConfiguration );
122+
// If there is an explicit JavaType, then prefer its recommended JDBC type
123+
final JavaType<J> javaType =
124+
explicitJavaType == null
125+
? jdbcType.getJdbcRecommendedJavaTypeMapping( length, scale, typeConfiguration )
126+
: explicitJavaType;
127+
return typeConfiguration.getBasicTypeRegistry().resolve( javaType, jdbcType );
128+
}
129+
catch (SQLException e) {
130+
throw getSqlExceptionHelper()
131+
.convert( e, "Unable to determine JDBC type code for ResultSet position " + position );
132+
}
133+
}
134+
135+
private <J> JdbcType jdbcType(
136+
JavaType<J> javaType,
137+
JdbcType resolvedJdbcType,
138+
int length, int precision, int scale,
139+
TypeConfiguration typeConfiguration) {
140+
return javaType.getRecommendedJdbcType(
141+
new JdbcTypeIndicators() {
142+
@Override
143+
public TypeConfiguration getTypeConfiguration() {
144+
return typeConfiguration;
145+
}
146+
147+
@Override
148+
public long getColumnLength() {
149+
return length;
150+
}
151+
152+
@Override
153+
public int getColumnPrecision() {
154+
return precision;
155+
}
156+
157+
@Override
158+
public int getColumnScale() {
159+
return scale;
160+
}
161+
162+
@Override
163+
public EnumType getEnumeratedType() {
164+
return resolvedJdbcType.isNumber() ? EnumType.ORDINAL : EnumType.STRING;
165+
}
166+
167+
@Override
168+
public Dialect getDialect() {
169+
return AbstractResultSetAccess.this.getDialect();
170+
}
171+
}
172+
);
173+
}
81174
}

hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/DeferredResultSetAccess.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public DeferredResultSetAccess(
8989
final String sql = jdbcSelect.getSqlString();
9090

9191
limit = queryOptions.getLimit();
92-
final boolean hasLimit = isHasLimit( jdbcSelect );
92+
final boolean hasLimit = hasLimit( jdbcSelect );
9393
limitHandler = hasLimit ? NoopLimitHandler.NO_LIMIT : dialect.getLimitHandler();
9494
final String sqlWithLimit = hasLimit ? sql : limitHandler.processSql( sql, limit, queryOptions );
9595

@@ -118,7 +118,7 @@ public DeferredResultSetAccess(
118118
}
119119
}
120120

121-
private boolean isHasLimit(JdbcOperationQuerySelect jdbcSelect) {
121+
private boolean hasLimit(JdbcOperationQuerySelect jdbcSelect) {
122122
return limit == null || limit.isEmpty() || jdbcSelect.usesLimitParameters();
123123
}
124124

@@ -183,7 +183,7 @@ public ResultSet getResultSet() {
183183
}
184184

185185
@Override
186-
public SessionFactoryImplementor getFactory() {
186+
protected SessionFactoryImplementor getFactory() {
187187
return executionContext.getSession().getFactory();
188188
}
189189

hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/DirectResultSetAccess.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ public DirectResultSetAccess(
2525
this.resultSetSource = resultSetSource;
2626
this.resultSet = resultSet;
2727

28-
persistenceContext.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().register( resultSet, resultSetSource );
28+
persistenceContext.getJdbcCoordinator().getLogicalConnection().getResourceRegistry()
29+
.register( resultSet, resultSetSource );
2930
}
3031

3132
@Override
@@ -34,7 +35,7 @@ public ResultSet getResultSet() {
3435
}
3536

3637
@Override
37-
public SessionFactoryImplementor getFactory() {
38+
protected SessionFactoryImplementor getFactory() {
3839
return getPersistenceContext().getFactory();
3940
}
4041

hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/ResultSetAccess.java

Lines changed: 12 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -5,151 +5,30 @@
55
package org.hibernate.sql.results.jdbc.internal;
66

77
import java.sql.ResultSet;
8-
import java.sql.ResultSetMetaData;
9-
import java.sql.SQLException;
108

11-
import org.hibernate.dialect.Dialect;
12-
import org.hibernate.engine.jdbc.spi.JdbcServices;
13-
import org.hibernate.engine.spi.SessionFactoryImplementor;
149
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
15-
import org.hibernate.type.BasicType;
16-
import org.hibernate.type.descriptor.java.JavaType;
17-
import org.hibernate.type.descriptor.jdbc.JdbcType;
18-
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
19-
import org.hibernate.type.spi.TypeConfiguration;
20-
21-
import jakarta.persistence.EnumType;
2210

2311
/**
2412
* Access to a JDBC {@link ResultSet} and information about it.
2513
*
2614
* @author Steve Ebersole
2715
*/
2816
public interface ResultSetAccess extends JdbcValuesMetadata {
17+
/**
18+
* The JDBC {@link ResultSet}
19+
*/
2920
ResultSet getResultSet();
30-
SessionFactoryImplementor getFactory();
21+
22+
/**
23+
* Release the JDBC {@link ResultSet}
24+
*/
3125
void release();
26+
3227
/**
33-
* The estimate for the amount of results that can be expected for pre-sizing collections.
34-
* May return zero or negative values if the count can not be reasonably estimated.
28+
* An estimate for the number of results that can be expected for pre-sizing collections.
29+
* May return zero or negative values if the count cannot be reasonably estimated.
30+
*
3531
* @since 6.6
3632
*/
37-
default int getResultCountEstimate() {
38-
return -1;
39-
}
40-
41-
default int getColumnCount() {
42-
try {
43-
return getResultSet().getMetaData().getColumnCount();
44-
}
45-
catch (SQLException e) {
46-
throw getFactory().getJdbcServices().getJdbcEnvironment().getSqlExceptionHelper()
47-
.convert( e, "Unable to access ResultSet column count" );
48-
}
49-
}
50-
51-
default int resolveColumnPosition(String columnName) {
52-
try {
53-
return getResultSet().findColumn( columnName );
54-
}
55-
catch (SQLException e) {
56-
throw getFactory().getJdbcServices().getJdbcEnvironment().getSqlExceptionHelper()
57-
.convert( e, "Unable to find column position by name" );
58-
}
59-
}
60-
61-
default String resolveColumnName(int position) {
62-
try {
63-
return getFactory().getJdbcServices().getJdbcEnvironment()
64-
.getDialect()
65-
.getColumnAliasExtractor()
66-
.extractColumnAlias( getResultSet().getMetaData(), position );
67-
}
68-
catch (SQLException e) {
69-
throw getFactory().getJdbcServices().getJdbcEnvironment().getSqlExceptionHelper()
70-
.convert( e, "Unable to find column name by position" );
71-
}
72-
}
73-
74-
@Override
75-
default <J> BasicType<J> resolveType(int position, JavaType<J> explicitJavaType, TypeConfiguration typeConfiguration) {
76-
final JdbcServices jdbcServices = getFactory().getJdbcServices();
77-
try {
78-
final ResultSetMetaData metaData = getResultSet().getMetaData();
79-
final String columnTypeName = metaData.getColumnTypeName( position );
80-
final int columnType = metaData.getColumnType( position );
81-
final int scale = metaData.getScale( position );
82-
final int precision = metaData.getPrecision( position );
83-
final int displaySize = metaData.getColumnDisplaySize( position );
84-
final Dialect dialect = jdbcServices.getDialect();
85-
final int length = dialect.resolveSqlTypeLength(
86-
columnTypeName,
87-
columnType,
88-
precision,
89-
scale,
90-
displaySize
91-
);
92-
final JdbcType resolvedJdbcType = dialect
93-
.resolveSqlTypeDescriptor(
94-
columnTypeName,
95-
columnType,
96-
length,
97-
scale,
98-
typeConfiguration.getJdbcTypeRegistry()
99-
);
100-
final JavaType<J> javaType;
101-
final JdbcType jdbcType;
102-
// If there is an explicit JavaType, then prefer its recommended JDBC type
103-
if ( explicitJavaType != null ) {
104-
javaType = explicitJavaType;
105-
jdbcType = explicitJavaType.getRecommendedJdbcType(
106-
new JdbcTypeIndicators() {
107-
@Override
108-
public TypeConfiguration getTypeConfiguration() {
109-
return typeConfiguration;
110-
}
111-
112-
@Override
113-
public long getColumnLength() {
114-
return length;
115-
}
116-
117-
@Override
118-
public int getColumnPrecision() {
119-
return precision;
120-
}
121-
122-
@Override
123-
public int getColumnScale() {
124-
return scale;
125-
}
126-
127-
@Override
128-
public EnumType getEnumeratedType() {
129-
return resolvedJdbcType.isNumber() ? EnumType.ORDINAL : EnumType.STRING;
130-
}
131-
132-
@Override
133-
public Dialect getDialect() {
134-
return getFactory().getJdbcServices().getDialect();
135-
}
136-
}
137-
);
138-
}
139-
else {
140-
jdbcType = resolvedJdbcType;
141-
javaType = jdbcType.getJdbcRecommendedJavaTypeMapping(
142-
length,
143-
scale,
144-
typeConfiguration
145-
);
146-
}
147-
return typeConfiguration.getBasicTypeRegistry().resolve( javaType, jdbcType );
148-
}
149-
catch (SQLException e) {
150-
throw jdbcServices.getSqlExceptionHelper()
151-
.convert( e, "Unable to determine JDBC type code for ResultSet position " + position );
152-
}
153-
}
154-
33+
int getResultCountEstimate();
15534
}

0 commit comments

Comments
 (0)