diff --git a/api/src/main/java/jakarta/data/repository/Delete.java b/api/src/main/java/jakarta/data/repository/Delete.java index ee5e015ea..214e06940 100644 --- a/api/src/main/java/jakarta/data/repository/Delete.java +++ b/api/src/main/java/jakarta/data/repository/Delete.java @@ -28,8 +28,9 @@ *
Lifecycle annotation for repository methods which perform delete operations.
* *The {@code Delete} annotation indicates that the annotated repository method deletes the state of one or more - * entities from the database. + * entities from the database. The method must follow one of the following patterns. *
+ *A {@code Delete} method might accept an instance or instances of an entity class. In this case, the method must * have exactly one parameter whose type is either: *
@@ -40,8 +41,6 @@ *The annotated method must be declared {@code void}. *
*All Jakarta Data providers are required to accept a {@code Delete} method which conforms to this signature. - * Application of the {@code Delete} annotation to a method with any other signature is not portable between Jakarta - * Data providers, excepting the specific case of a repository method with no parameters, as described below. *
*For example, consider an interface representing a garage:
*@@ -57,6 +56,7 @@ * if the entity with a matching identifier does not have a matching version, the annotated method must raise * {@link jakarta.data.exceptions.OptimisticLockingFailureException}. * + *Without Parameters
*Alternatively, the {@code Delete} annotation may be applied to a repository method with no parameters, indicating * that the annotated method deletes all instances of the primary entity type. In this case, the annotated method must * either be declared {@code void}, or return {@code int} or {@code long}. @@ -64,7 +64,7 @@ *
Annotations such as {@code @Find}, {@code @Query}, {@code @Insert}, {@code @Update}, {@code @Delete}, and * {@code @Save} are mutually-exclusive. A given method of a repository interface may have at most one {@code @Find} * annotation, lifecycle annotation, or query annotation. - *
*/ @Documented @Retention(RetentionPolicy.RUNTIME) diff --git a/api/src/main/java/jakarta/data/repository/Insert.java b/api/src/main/java/jakarta/data/repository/Insert.java index 7fef9eccd..2e01fabfa 100644 --- a/api/src/main/java/jakarta/data/repository/Insert.java +++ b/api/src/main/java/jakarta/data/repository/Insert.java @@ -69,7 +69,7 @@ *Annotations such as {@code @Find}, {@code @Query}, {@code @Insert}, {@code @Update}, {@code @Delete}, and * {@code @Save} are mutually-exclusive. A given method of a repository interface may have at most one {@code @Find} * annotation, lifecycle annotation, or query annotation. - *
*/ @Documented @Retention(RetentionPolicy.RUNTIME) diff --git a/api/src/main/java/jakarta/data/repository/Save.java b/api/src/main/java/jakarta/data/repository/Save.java index d227665d8..f5216aebc 100644 --- a/api/src/main/java/jakarta/data/repository/Save.java +++ b/api/src/main/java/jakarta/data/repository/Save.java @@ -64,7 +64,7 @@ *Annotations such as {@code @Find}, {@code @Query}, {@code @Insert}, {@code @Update}, {@code @Delete}, and * {@code @Save} are mutually-exclusive. A given method of a repository interface may have at most one {@code @Find} * annotation, lifecycle annotation, or query annotation. - *
* * @see Insert * @see Update diff --git a/api/src/main/java/jakarta/data/repository/Update.java b/api/src/main/java/jakarta/data/repository/Update.java index cf05d7f1a..ceb86bd22 100644 --- a/api/src/main/java/jakarta/data/repository/Update.java +++ b/api/src/main/java/jakarta/data/repository/Update.java @@ -30,7 +30,7 @@ *The {@code Update} annotation indicates that the annotated repository method updates the state of one or more * entities already held in the database. *
- *An {@code Update} method might accept an instance or instances of an entity class. In this case, the method must + *
An {@code Update} method accepts an instance or instances of an entity class. The method must * have exactly one parameter whose type is either: *
*
* All Jakarta Data providers are required to accept an {@code Update} method which conforms to this signature. - * Application of the {@code Update} annotation to a method with any other signature is not portable between Jakarta - * Data providers. - *
* *For example, consider an interface representing a garage:
*@@ -73,7 +70,7 @@ *Annotations such as {@code @Find}, {@code @Query}, {@code @Insert}, {@code @Update}, {@code @Delete}, and * {@code @Save} are mutually-exclusive. A given method of a repository interface may have at most one {@code @Find} * annotation, lifecycle annotation, or query annotation. - *
*/ @Documented @Retention(RetentionPolicy.RUNTIME) diff --git a/tck/src/main/java/ee/jakarta/tck/data/standalone/persistence/Catalog.java b/tck/src/main/java/ee/jakarta/tck/data/standalone/persistence/Catalog.java index 8500a754c..71c3cb38b 100644 --- a/tck/src/main/java/ee/jakarta/tck/data/standalone/persistence/Catalog.java +++ b/tck/src/main/java/ee/jakarta/tck/data/standalone/persistence/Catalog.java @@ -18,12 +18,14 @@ import java.util.Collection; import java.util.LinkedList; import java.util.List; +import java.util.Optional; import java.util.stream.Stream; import jakarta.data.Order; import jakarta.data.Streamable; import jakarta.data.repository.DataRepository; import jakarta.data.repository.Delete; +import jakarta.data.repository.Find; import jakarta.data.repository.Insert; import jakarta.data.repository.OrderBy; import jakarta.data.repository.Param; @@ -44,6 +46,9 @@ public interface Catalog extends DataRepository{ @Insert Product[] addMultiple(Product... products); + @Find + Optional get(String productNum); + @Update Product modify(Product product); diff --git a/tck/src/main/java/ee/jakarta/tck/data/standalone/persistence/PersistenceEntityTests.java b/tck/src/main/java/ee/jakarta/tck/data/standalone/persistence/PersistenceEntityTests.java index 325e1f20e..d02c2b401 100644 --- a/tck/src/main/java/ee/jakarta/tck/data/standalone/persistence/PersistenceEntityTests.java +++ b/tck/src/main/java/ee/jakarta/tck/data/standalone/persistence/PersistenceEntityTests.java @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -150,7 +151,14 @@ public void testInsertEntityThatAlreadyExists() { // expected } - assertEquals(true, catalog.remove(prod1)); + Optional result; + result = catalog.get("TEST-PROD-94"); + assertEquals(true, result.isPresent()); + + catalog.remove(prod1); + + result = catalog.get("TEST-PROD-94"); + assertEquals(false, result.isPresent()); } @Assertion(id = "133", strategy = "Use a repository method with the Like keyword.") @@ -352,9 +360,24 @@ public void testVersionedInsertUpdateDelete() { prod2.setPrice(1.34); assertEquals(null, catalog.modify(prod2)); - assertEquals(true, catalog.remove(prod1)); - assertEquals(false, catalog.remove(prod1)); // already removed - assertEquals(false, catalog.remove(prod2)); // still at old version + catalog.remove(prod1); + + Optional found = catalog.get("TEST-PROD-91"); + assertEquals(false, found.isPresent()); + + try { + catalog.remove(prod1); // already removed + fail("Must raise OptimisticLockingFailureException for entity that was already removed from the database."); + } catch (OptimisticLockingFailureException x) { + // expected + } + + try { + catalog.remove(prod2); // still at old version + fail("Must raise OptimisticLockingFailureException for entity with non-matching version."); + } catch (OptimisticLockingFailureException x) { + // expected + } assertEquals(1L, catalog.deleteByProductNumLike("TEST-PROD-%")); }