diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolverTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolverTest.java index ff62406..3bb85b2 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolverTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/NestedSpecificationResolverTest.java @@ -111,7 +111,10 @@ void allAnd() { .extracting("specs", LIST) .hasSize(2); depth1.first().isInstanceOf(Equals.class); - depth1 + var depth2 = + depth1.element(1).isInstanceOf(Conjunction.class).extracting("specs", LIST).hasSize(2); + depth2.first().isInstanceOf(Equals.class); + depth2 .element(1) .isInstanceOf(Conjunction.class) .extracting("specs", LIST) @@ -389,7 +392,7 @@ public static class NestedAnd { @AllArgsConstructor public static class NestedInNestedAnd { - @NestedSpec String name; + @Spec String name; } @Builder diff --git a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ReflectionDatabindTest.java b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ReflectionDatabindTest.java index 1fff467..180ba22 100644 --- a/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ReflectionDatabindTest.java +++ b/mapper/src/test/java/tw/com/softleader/data/jpa/spec/ReflectionDatabindTest.java @@ -29,6 +29,7 @@ import java.util.Collection; import java.util.Optional; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import org.junit.jupiter.api.Test; @@ -49,17 +50,28 @@ void fireOnlyOnce() { assertThat(databind).hasSize(5); - var numberOfThreads = 1; + // Release every thread at the same instant so multiple threads race into + // getFieldValue() on the *same* Databind instances and genuinely contend on + // the AtomicBoolean CAS + CountDownLatch dedup. + var numberOfThreads = 32; var service = newFixedThreadPool(numberOfThreads); - var latch = new CountDownLatch(numberOfThreads); + var startBarrier = new CyclicBarrier(numberOfThreads); + var done = new CountDownLatch(numberOfThreads); for (int i = 0; i < numberOfThreads; i++) { service.submit( () -> { - databind.forEach(Databind::getFieldValue); - latch.countDown(); + try { + startBarrier.await(); + databind.forEach(Databind::getFieldValue); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + done.countDown(); + } }); } - latch.await(); + done.await(); + service.shutdown(); databind.forEach( bind -> {