Skip to content
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

Distinct ClientPreparedStatement objects incorrectly have same hashCode and match with equals() #308

Closed
buitcj opened this issue Nov 14, 2022 · 7 comments
Labels
bug Something isn't working

Comments

@buitcj
Copy link
Contributor

buitcj commented Nov 14, 2022

Describe the bug

Distinct ClientPreparedStatements sharing a ConnectionProxy will all use the hashCode() and equals() of the ConnectionProxy and therefore will all have the same hash code and be equals via the equals() call.

This is a problem not only because fundamentally the objects are different so they should have different hash codes and not be equal, but also because when using the AWS Aurora MySQL driver with Hibernate 5, the ClientPreparedStatements will be registered in ResourceRegistryStandardImpl here https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/resource/jdbc/internal/ResourceRegistryStandardImpl.java#L87 . This code will throw an exception when the Statement (key) was already registered. Multiple different statements with the same hashCode() that are equal via the equals() will cause this problem.

Expected Behavior

Multiple ClientPreparedStatements using the same ConnectionProxy should have different hash code values and not be equal via equals()

Current Behavior

Normally, Hibernate code will throw an exception when the Statement (key) was already registered. It detects this by seeing if the key already exists in its map. Using the AWS Aurora MySQL driver, multiple different statements with the same hashCode() that are equal via the equals() will cause a "JDBC Statement already registered" even if the Statements are not the same.

Reproduction Steps

Using the same Hibernate Session, call prepareQueryStatement() with two different Statements that use different SQL queries.

Expected: Successful registration of the two Statements

Actual: First ClientPreparedStatement registers successfully but the second registration has an HibernateException thrown from ResourceRegistryStandardImpl with message JDBC Statement already registered

Possible Solution

One possible solution is to simply not let the proxy directly execute equals() and hashCode() and instead defer to the underlying Statement.

src/main/user-impl/java/com/mysql/cj/jdbc/ha/ConnectionProxy.java implements invoke() (https://github.com/awslabs/aws-mysql-jdbc/blob/main/src/main/user-impl/java/com/mysql/cj/jdbc/ha/ConnectionProxy.java#L312) which will detect if the method is equals or hashCode (https://github.com/awslabs/aws-mysql-jdbc/blob/main/src/main/user-impl/java/com/mysql/cj/jdbc/ha/ConnectionProxy.java#L296) and if so, it uses the implementation of the ConnectionProxy instead of the implementation of the underlying object (https://github.com/awslabs/aws-mysql-jdbc/blob/main/src/main/user-impl/java/com/mysql/cj/jdbc/ha/ConnectionProxy.java#L267). In this case, the underlying object is the ClientPreparedStatement. Two different ClientPreparedStatement objects that share the same ConnectionProxy will be equal because they share the same hash code and equals() will evaluate to true.

Additional Information/Context

No response

The AWS JDBC Driver for MySQL version used

1.1.1 (and 1.1.0)

JDK version used

1.8

Operating System and version

MacOS Monterey 12.3.1

@buitcj buitcj added the bug Something isn't working label Nov 14, 2022
sergiyvamz pushed a commit that referenced this issue Nov 14, 2022
sergiyvamz added a commit that referenced this issue Nov 15, 2022
Co-authored-by: sergiyv-bitquill <sergiyv@bitquilltech.com>
@sergiyvamz
Copy link
Contributor

Hello @buitcj

The fix for the issue has been applied. Will you be able to test out a snapshot build here and let us know if the issue persists?

Thank you!

@buitcj
Copy link
Contributor Author

buitcj commented Nov 15, 2022

Appears to work - thanks @sergiyvamz!

When should we expect 1.1.2 to be released? What is the release schedule for the driver?

@buitcj buitcj closed this as completed Nov 15, 2022
@buitcj
Copy link
Contributor Author

buitcj commented Nov 18, 2022

@sergiyvamz friendly bump! if you don't have the answer that's fine, but I just want to have a contingency plan for our own software release if we're not going to get this fix in an official version before our deadlines

@davecramer
Copy link
Contributor

@buitcj we will get back to you ASAP with an answer.

@awslabs awslabs deleted a comment from matthewh-BQ Nov 18, 2022
@hsuamz
Copy link
Contributor

hsuamz commented Nov 18, 2022

Hello @buitcj, we will be including an additional fix before we release an updated driver. We are planning to release 1.1.2 early next week.

Does this align with your deadlines?

Thanks,

Matthew

@buitcj
Copy link
Contributor Author

buitcj commented Nov 18, 2022

@hsuamz Yes it does. Thanks for the update

@karenc-bq
Copy link
Contributor

Hi @buitcj, version 1.1.2 of the driver has been released, thank you for your patience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants