@@ -110,7 +110,8 @@ native void nativeSetParameter(long handle, int entityId, int propertyId, @Nulla
110
110
private final int queryAttempts ;
111
111
private static final int INITIAL_RETRY_BACK_OFF_IN_MS = 10 ;
112
112
113
- long handle ;
113
+ // volatile so checkOpen() is more up-to-date (no need for synchronized; it's a race anyway)
114
+ volatile long handle ;
114
115
115
116
Query (Box <T > box , long queryHandle , @ Nullable List <EagerRelation <T , ?>> eagerRelations , @ Nullable QueryFilter <T > filter ,
116
117
@ Nullable Comparator <T > comparator ) {
@@ -135,7 +136,12 @@ protected void finalize() throws Throwable {
135
136
}
136
137
137
138
/**
138
- * If possible, try to close the query once you are done with it to reclaim resources immediately.
139
+ * Closes this query and frees used resources.
140
+ * <p>
141
+ * If possible, call this always once done with this. Otherwise, will be called once this is finalized (e.g. garbage
142
+ * collected).
143
+ * <p>
144
+ * Calling any other methods of this afterwards will throw an {@link IllegalStateException}.
139
145
*/
140
146
public synchronized void close () {
141
147
if (handle != 0 ) {
@@ -256,6 +262,7 @@ public long[] findIds() {
256
262
*/
257
263
@ Nonnull
258
264
public long [] findIds (final long offset , final long limit ) {
265
+ checkOpen ();
259
266
return box .internalCallWithReaderHandle (cursorHandle -> nativeFindIds (handle , cursorHandle , offset , limit ));
260
267
}
261
268
@@ -294,6 +301,7 @@ public PropertyQuery property(Property<T> property) {
294
301
}
295
302
296
303
<R > R callInReadTx (Callable <R > callable ) {
304
+ checkOpen ();
297
305
return store .callInReadTxWithRetry (callable , queryAttempts , INITIAL_RETRY_BACK_OFF_IN_MS , true );
298
306
}
299
307
@@ -308,6 +316,7 @@ <R> R callInReadTx(Callable<R> callable) {
308
316
*/
309
317
public void forEach (final QueryConsumer <T > consumer ) {
310
318
ensureNoComparator ();
319
+ checkOpen (); // findIds also checks, but throw early outside of transaction.
311
320
box .getStore ().runInReadTx (() -> {
312
321
LazyList <T > lazyList = new LazyList <>(box , findIds (), false );
313
322
int size = lazyList .size ();
@@ -384,6 +393,7 @@ void resolveEagerRelation(@Nonnull T entity, EagerRelation<T, ?> eagerRelation)
384
393
385
394
/** Returns the count of Objects matching the query. */
386
395
public long count () {
396
+ checkOpen ();
387
397
ensureNoFilter ();
388
398
return box .internalCallWithReaderHandle (cursorHandle -> nativeCount (handle , cursorHandle ));
389
399
}
@@ -392,6 +402,7 @@ public long count() {
392
402
* Sets a parameter previously given to the {@link QueryBuilder} to a new value.
393
403
*/
394
404
public Query <T > setParameter (Property <?> property , String value ) {
405
+ checkOpen ();
395
406
nativeSetParameter (handle , property .getEntityId (), property .getId (), null , value );
396
407
return this ;
397
408
}
@@ -402,6 +413,7 @@ public Query<T> setParameter(Property<?> property, String value) {
402
413
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
403
414
*/
404
415
public Query <T > setParameter (String alias , String value ) {
416
+ checkOpen ();
405
417
nativeSetParameter (handle , 0 , 0 , alias , value );
406
418
return this ;
407
419
}
@@ -410,6 +422,7 @@ public Query<T> setParameter(String alias, String value) {
410
422
* Sets a parameter previously given to the {@link QueryBuilder} to a new value.
411
423
*/
412
424
public Query <T > setParameter (Property <?> property , long value ) {
425
+ checkOpen ();
413
426
nativeSetParameter (handle , property .getEntityId (), property .getId (), null , value );
414
427
return this ;
415
428
}
@@ -420,6 +433,7 @@ public Query<T> setParameter(Property<?> property, long value) {
420
433
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
421
434
*/
422
435
public Query <T > setParameter (String alias , long value ) {
436
+ checkOpen ();
423
437
nativeSetParameter (handle , 0 , 0 , alias , value );
424
438
return this ;
425
439
}
@@ -428,6 +442,7 @@ public Query<T> setParameter(String alias, long value) {
428
442
* Sets a parameter previously given to the {@link QueryBuilder} to a new value.
429
443
*/
430
444
public Query <T > setParameter (Property <?> property , double value ) {
445
+ checkOpen ();
431
446
nativeSetParameter (handle , property .getEntityId (), property .getId (), null , value );
432
447
return this ;
433
448
}
@@ -438,6 +453,7 @@ public Query<T> setParameter(Property<?> property, double value) {
438
453
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
439
454
*/
440
455
public Query <T > setParameter (String alias , double value ) {
456
+ checkOpen ();
441
457
nativeSetParameter (handle , 0 , 0 , alias , value );
442
458
return this ;
443
459
}
@@ -481,6 +497,7 @@ public Query<T> setParameter(String alias, boolean value) {
481
497
* Sets a parameter previously given to the {@link QueryBuilder} to new values.
482
498
*/
483
499
public Query <T > setParameters (Property <?> property , long value1 , long value2 ) {
500
+ checkOpen ();
484
501
nativeSetParameters (handle , property .getEntityId (), property .getId (), null , value1 , value2 );
485
502
return this ;
486
503
}
@@ -491,6 +508,7 @@ public Query<T> setParameters(Property<?> property, long value1, long value2) {
491
508
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
492
509
*/
493
510
public Query <T > setParameters (String alias , long value1 , long value2 ) {
511
+ checkOpen ();
494
512
nativeSetParameters (handle , 0 , 0 , alias , value1 , value2 );
495
513
return this ;
496
514
}
@@ -499,6 +517,7 @@ public Query<T> setParameters(String alias, long value1, long value2) {
499
517
* Sets a parameter previously given to the {@link QueryBuilder} to new values.
500
518
*/
501
519
public Query <T > setParameters (Property <?> property , int [] values ) {
520
+ checkOpen ();
502
521
nativeSetParameters (handle , property .getEntityId (), property .getId (), null , values );
503
522
return this ;
504
523
}
@@ -509,6 +528,7 @@ public Query<T> setParameters(Property<?> property, int[] values) {
509
528
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
510
529
*/
511
530
public Query <T > setParameters (String alias , int [] values ) {
531
+ checkOpen ();
512
532
nativeSetParameters (handle , 0 , 0 , alias , values );
513
533
return this ;
514
534
}
@@ -517,6 +537,7 @@ public Query<T> setParameters(String alias, int[] values) {
517
537
* Sets a parameter previously given to the {@link QueryBuilder} to new values.
518
538
*/
519
539
public Query <T > setParameters (Property <?> property , long [] values ) {
540
+ checkOpen ();
520
541
nativeSetParameters (handle , property .getEntityId (), property .getId (), null , values );
521
542
return this ;
522
543
}
@@ -527,6 +548,7 @@ public Query<T> setParameters(Property<?> property, long[] values) {
527
548
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
528
549
*/
529
550
public Query <T > setParameters (String alias , long [] values ) {
551
+ checkOpen ();
530
552
nativeSetParameters (handle , 0 , 0 , alias , values );
531
553
return this ;
532
554
}
@@ -535,6 +557,7 @@ public Query<T> setParameters(String alias, long[] values) {
535
557
* Sets a parameter previously given to the {@link QueryBuilder} to new values.
536
558
*/
537
559
public Query <T > setParameters (Property <?> property , double value1 , double value2 ) {
560
+ checkOpen ();
538
561
nativeSetParameters (handle , property .getEntityId (), property .getId (), null , value1 , value2 );
539
562
return this ;
540
563
}
@@ -545,6 +568,7 @@ public Query<T> setParameters(Property<?> property, double value1, double value2
545
568
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
546
569
*/
547
570
public Query <T > setParameters (String alias , double value1 , double value2 ) {
571
+ checkOpen ();
548
572
nativeSetParameters (handle , 0 , 0 , alias , value1 , value2 );
549
573
return this ;
550
574
}
@@ -553,6 +577,7 @@ public Query<T> setParameters(String alias, double value1, double value2) {
553
577
* Sets a parameter previously given to the {@link QueryBuilder} to new values.
554
578
*/
555
579
public Query <T > setParameters (Property <?> property , String [] values ) {
580
+ checkOpen ();
556
581
nativeSetParameters (handle , property .getEntityId (), property .getId (), null , values );
557
582
return this ;
558
583
}
@@ -563,6 +588,7 @@ public Query<T> setParameters(Property<?> property, String[] values) {
563
588
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
564
589
*/
565
590
public Query <T > setParameters (String alias , String [] values ) {
591
+ checkOpen ();
566
592
nativeSetParameters (handle , 0 , 0 , alias , values );
567
593
return this ;
568
594
}
@@ -571,6 +597,7 @@ public Query<T> setParameters(String alias, String[] values) {
571
597
* Sets a parameter previously given to the {@link QueryBuilder} to new values.
572
598
*/
573
599
public Query <T > setParameters (Property <?> property , String key , String value ) {
600
+ checkOpen ();
574
601
nativeSetParameters (handle , property .getEntityId (), property .getId (), null , key , value );
575
602
return this ;
576
603
}
@@ -581,6 +608,7 @@ public Query<T> setParameters(Property<?> property, String key, String value) {
581
608
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
582
609
*/
583
610
public Query <T > setParameters (String alias , String key , String value ) {
611
+ checkOpen ();
584
612
nativeSetParameters (handle , 0 , 0 , alias , key , value );
585
613
return this ;
586
614
}
@@ -589,6 +617,7 @@ public Query<T> setParameters(String alias, String key, String value) {
589
617
* Sets a parameter previously given to the {@link QueryBuilder} to new values.
590
618
*/
591
619
public Query <T > setParameter (Property <?> property , byte [] value ) {
620
+ checkOpen ();
592
621
nativeSetParameter (handle , property .getEntityId (), property .getId (), null , value );
593
622
return this ;
594
623
}
@@ -599,6 +628,7 @@ public Query<T> setParameter(Property<?> property, byte[] value) {
599
628
* @param alias as defined using {@link QueryBuilder#parameterAlias(String)}.
600
629
*/
601
630
public Query <T > setParameter (String alias , byte [] value ) {
631
+ checkOpen ();
602
632
nativeSetParameter (handle , 0 , 0 , alias , value );
603
633
return this ;
604
634
}
@@ -609,6 +639,7 @@ public Query<T> setParameter(String alias, byte[] value) {
609
639
* @return count of removed Objects
610
640
*/
611
641
public long remove () {
642
+ checkOpen ();
612
643
ensureNoFilter ();
613
644
return box .internalCallWithWriterHandle (cursorHandle -> nativeRemove (handle , cursorHandle ));
614
645
}
@@ -632,6 +663,7 @@ public long remove() {
632
663
* it may be GCed and observers may become stale (won't receive anymore data).
633
664
*/
634
665
public SubscriptionBuilder <List <T >> subscribe () {
666
+ checkOpen ();
635
667
return new SubscriptionBuilder <>(publisher , null );
636
668
}
637
669
@@ -663,6 +695,7 @@ public void publish() {
663
695
* Note: the format of the returned string may change without notice.
664
696
*/
665
697
public String describe () {
698
+ checkOpen ();
666
699
return nativeToString (handle );
667
700
}
668
701
@@ -673,7 +706,17 @@ public String describe() {
673
706
* Note: the format of the returned string may change without notice.
674
707
*/
675
708
public String describeParameters () {
709
+ checkOpen ();
676
710
return nativeDescribeParameters (handle );
677
711
}
678
712
713
+ /**
714
+ * Throws if {@link #close()} has been called for this.
715
+ */
716
+ private void checkOpen () {
717
+ if (handle == 0 ) {
718
+ throw new IllegalStateException ("This query is closed. Build and use a new one." );
719
+ }
720
+ }
721
+
679
722
}
0 commit comments