-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
HHH-19602 - Adjust JdbcOperation to allow more-than-one statement #10752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcAction.java
Fixed
Show fixed
Hide fixed
hibernate-core/src/main/java/org/hibernate/sql/exec/spi/DatabaseOperationSelect.java
Fixed
Show fixed
Hide fixed
...rnate-core/src/test/java/org/hibernate/orm/test/sql/exec/spi/DatabaseOperationSmokeTest.java
Fixed
Show fixed
Hide fixed
...rnate-core/src/test/java/org/hibernate/orm/test/sql/exec/spi/DatabaseOperationSmokeTest.java
Fixed
Show fixed
Hide fixed
* @param jdbcConnection The JDBC Connection. | ||
* @param executionContext Access to contextual information useful while executing. | ||
*/ | ||
void performPostAction(StatementAccess jdbcStatementAccess, Connection jdbcConnection, ExecutionContext executionContext); |
Check notice
Code scanning / CodeQL
Useless parameter Note
* @param jdbcConnection The JDBC Connection. | ||
* @param executionContext Access to contextual information useful while executing. | ||
*/ | ||
void performPreAction(StatementAccess jdbcStatementAccess, Connection jdbcConnection, ExecutionContext executionContext); |
Check notice
Code scanning / CodeQL
Useless parameter Note
...rnate-core/src/test/java/org/hibernate/orm/test/sql/exec/spi/DatabaseOperationSmokeTest.java
Fixed
Show fixed
Hide fixed
LGTM |
In this last commit I have a generally working solution for simple cases, where I think the approach is one that is feasible for a first pass. It has some limitations currently -
It also requires some changes to how JdbcSelectExecutor and especically JdbcValuesSourceProcessingState operate. We could mitigate this by instead putting the new LoadedValuesCollector reference on ExecutionContext (similar to Callback/AfterLoadAction), but that has always felt fugly. Anyway, see FollowOnLockingParadigmTests#testFollowOnLockingFlow for the flow. Anyway, what happens is that we issue the first selection (without locking) and load results as mormal. As part of that loading, LoadedValuesCollector is used to collect things that need to be locked. A post-action then is used to leverage the LoadedValuesCollector values and issue locking selects against each table, ultimately refreshing the state of the entity (and its loaded-state). So for example, from the test we have the primary operation, the select without locking - select
t1_0.id,
m1_0.team_fk,
m1_0.id,
m1_0.name,
t1_0.name
from
teams t1_0
left join
persons m1_0
on t1_0.id=m1_0.team_fk
where
t1_0.id=? Which yields: Loaded root entities:
org.hibernate.orm.test.sql.exec.op.Team#1
Loaded non-root entities:
org.hibernate.orm.test.sql.exec.op.Person#1
org.hibernate.orm.test.sql.exec.op.Person#2
org.hibernate.orm.test.sql.exec.op.Person#3
Loaded collections:
org.hibernate.orm.test.sql.exec.op.Team.members#1 And then 2 additional queries - select
tbl.id,
tbl.name
from
teams tbl
where
tbl.id in (?)
for
update
select
tbl.id,
tbl.name
from
persons tbl
where
tbl.id in (?, ?, ?)
for
update As the results of these locking queries are processed, we update the "loaded state" and instance state for the entities. |
00a91d7
to
afbcc08
Compare
hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstTranslator.java
Fixed
Show fixed
Hide fixed
hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java
Fixed
Show fixed
Hide fixed
...ore/src/main/java/org/hibernate/sql/ops/internal/JdbcValuesSourceProcessingStateCreator.java
Fixed
Show fixed
Hide fixed
hibernate-core/src/main/java/org/hibernate/sql/ops/internal/lock/SpecialResultSetAccess.java
Fixed
Show fixed
Hide fixed
hibernate-core/src/main/java/org/hibernate/sql/ops/spi/DatabaseSelect.java
Fixed
Show fixed
Hide fixed
hibernate-core/src/test/java/org/hibernate/orm/test/sql/exec/op/DatabaseSelectSmokeTests.java
Fixed
Show fixed
Hide fixed
hibernate-core/src/test/java/org/hibernate/orm/test/sql/exec/op/DatabaseSelectSmokeTests.java
Fixed
Show fixed
Hide fixed
hibernate-core/src/test/java/org/hibernate/orm/test/sql/exec/op/DatabaseSelectSmokeTests.java
Fixed
Show fixed
Hide fixed
BiConsumer<Integer, PreparedStatement> expectationCheck, | ||
ExecutionContext executionContext) { | ||
final JdbcMutationExecutor jdbcMutationExecutor = executionContext.getSession().getJdbcServices().getJdbcMutationExecutor(); | ||
return jdbcMutationExecutor.execute( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing performPreActions()
and performPostActions()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just focusing on selections for now. And in fact, I'm folding all this into JdbcOperation itself locally. These DatabaseOPeration contracts are going away. (from the Zulip discussion)
But larger picture, implementing this generically for mutations is going to be a pain because of the difference in how mutations work between queries and model mutuations.
hibernate-core/src/main/java/org/hibernate/sql/ops/internal/AbstractDatabaseOperation.java
Outdated
Show resolved
Hide resolved
hibernate-core/src/main/java/org/hibernate/sql/ops/internal/lock/FollowOnLockingAction.java
Outdated
Show resolved
Hide resolved
afbcc08
to
56f18a4
Compare
A few notes:
|
} | ||
|
||
default RootGraphImplementor createRootGraph(SharedSessionContractImplementor session) { | ||
if ( getRepresentationStrategy() instanceof EntityRepresentationStrategyMap mapRep ) { |
Check notice
Code scanning / CodeQL
Unread local variable Note
final Map<Object, EntityDetails> entityDetailsMap = resolveEntityKeys( entityKeys, executionContext ); | ||
|
||
entityMappingType.forEachAttributeMapping( (index, attributeMapping) -> { | ||
if ( attributeMapping instanceof PluralAttributeMapping pluralAttributeMapping ) { |
Check notice
Code scanning / CodeQL
Unread local variable Note
hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/TableSegment.java
Fixed
Show fixed
Hide fixed
One thing I do still want to look into is: // todo (JdbcOperation) : Consider leveraging approach based on Dialect#useArrayForMultiValuedParameters Also need to be sensitive to the number of keys to load and the number of supported parameters when using an in-list predicate |
List<Product> products = session.createQuery( "select p from Product p left join p.vehicle v on v.id is null", Product.class ) | ||
.setHibernateLockMode( PESSIMISTIC_WRITE ) | ||
.setFollowOnStrategy( Locking.FollowOn.DISALLOW ) | ||
.setFirstResult( 40 ) | ||
.setMaxResults( 10 ) | ||
.getResultList(); |
Check notice
Code scanning / CodeQL
Unread local variable Note test
List<Vehicle> vehicles = session.createQuery( "select v from Vehicle v", Vehicle.class ) | ||
.setHibernateLockMode( PESSIMISTIC_WRITE ) | ||
.setFollowOnStrategy( Locking.FollowOn.DISALLOW ) | ||
.getResultList(); |
Check notice
Code scanning / CodeQL
Unread local variable Note test
# Conflicts: # hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
# Conflicts: # hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/DeferredResultSetAccess.java # Conflicts: # hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/DeferredResultSetAccess.java
HHH-19782 - Oracle support for locking across joins
HHH-19782 - Oracle support for locking across joins
0598345
to
4e747e3
Compare
hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/LockingAction.java
Fixed
Show fixed
Hide fixed
HHH-19782 - Oracle support for locking across joins
HHH-19782 - Oracle support for locking across joins
HHH-19513 - Follow-on locking does not lock element-collection tables
Rebased and applied manually |
HHH-19602 - Adjust JdbcOperation to allow more-than-one statement
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.
https://hibernate.atlassian.net/browse/HHH-19602