-
Notifications
You must be signed in to change notification settings - Fork 165
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
Fix Session.load/queryForObject nullability #765
Fix Session.load/queryForObject nullability #765
Conversation
Good catch and bummer on my side :/ I'm gonna deal with the warning in the readme and changelog. But I think it's much better to annoy people with a breaking change in the API in a patch release than having issues around nullability in Kotlin. WDYT, @meistermeier ? |
I forgot to mention that neo4j-ogm/embedded-driver/src/main/java/org/neo4j/ogm/drivers/embedded/driver/EmbeddedDriver.java Lines 181 to 188 in 0fafd9b
if the driver is closed: neo4j-ogm/embedded-driver/src/main/java/org/neo4j/ogm/drivers/embedded/driver/EmbeddedDriver.java Lines 172 to 179 in 0fafd9b
But I think that may need a different fix, maybe make sure EmbeddedDriver doesn't return null? (BoltDriver will initialize itself, it'll never be null) Shall I open a bug for this to figure out? |
I think it's ok to change the unwrap extension to return possible I'd rather see bolt and embedded driver behave the same I think: So either return |
…hods. * Add failing tests for load/quaryForObject returning null * Fix wrong signature (see called function's JavaDoc) * Fix compilation errors after changing signature (this is expected for every user) * Fix warnings in KotlinInteropTest.kt Co-authored-by: Michael Simons <michael.simons@neo4j.com>
[FIX] Add functions with correct nullability and use code that's like the reported neo4j/neo4j-ogm#765
* Update versions: Neo4J OGM 3.2.24 and Neo4J 4.2.0 * Remove now unnecessary hack: neo4j-ogm-core:3.2.24 depends on classgraph 4.8.86 * Fix tests by using an earlier version of Neo4jMatchers (3.4.9) and adapting it to latest. * Migrate to Cypher 4 syntax for params * Use explicit transaction name in beginTx().use {} * Migrate CREATE UNIQUE to MERGE * Introduce TimestampConverter to explicitly save with custom serialization * Ignore unsafe reflective calls * Fix logging of Neo4J OGM in tests * Work around for duplicate ID in XML * Work around neo4j/neo4j#12770 (SLF4J: Class path contains multiple SLF4J bindings.) * Bump minor version to fix neo4j/neo4j#12655 * Fix: remove polyfills, neo4j/neo4j-ogm#765 is merged. * Fix flaky test: separate JFixture objects would keep creating duplicate IDs at random. Sharing the instance will always create unique integers.
Description
Add tests and fix nullability for these methods that can and will return null.
Related Issue
See first commit for failing tests for repro.
Motivation and Context
The mentioned method explicitly declare nullability, but they're restricted in the Kotlin extension functions.
neo4j-ogm/core/src/main/java/org/neo4j/ogm/session/Session.java
Lines 489 to 494 in 0fafd9b
neo4j-ogm/core/src/main/java/org/neo4j/ogm/session/Session.java
Lines 496 to 501 in 0fafd9b
neo4j-ogm/core/src/main/java/org/neo4j/ogm/session/Session.java
Lines 609 to 613 in 0fafd9b
This causes a problem when used like this:
Notice that because
queryForObject
declared a non-null return type, I can too. But when I callfind
with a wrong ID, it'll blow up with:This means that a simple inline utility function changes behavior of the method on the interface.
Note that
T
is restricted to non-null (: Any
) in generics. AddingT?
as return value is explicitly making this nullable, which it should be. Alternatively changing to<T: Any?>
would work too, but it's not safe as seen here:notice how specifying the type argument for the function (explicit or inferred doesn't matter), we're telling Kotlin one thing, but receiving another. See how a non-null inferred
result
is actually passing anassertNull
test?! 😨 If it was actually using that variable, it would blow up with NPE.The big problem here is that in Kotlin a change like this is like changing from an interface to a concrete type in Java. It's going to break practically everyone who used this method. The fix is easy though: either
!!
if they're sure the value they're querying is there, or add a null check (if
/?.
/?: fallback
/?: return
/?: error()
) to signal appropriately for their project.How Has This Been Tested?
Added unit tests.
TODO: should I add an integration test too for not found value being null?
Types of changes
It is a breaking change because every time someone used this function they assumed non-null, see context above.
Checklist:
As in: a big warning in Changelog and release notes.