Skip to content

Commit 0c892b3

Browse files
authored
Merge pull request #28339 from njr-11/22762-jdql-update-and-delete-with-record-entity
JDQL update and delete with record entity, and omitted select clause returning different type
2 parents c810a5d + 15c8f48 commit 0c892b3

File tree

10 files changed

+273
-172
lines changed

10 files changed

+273
-172
lines changed

dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/EntityManagerBuilder.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import com.ibm.websphere.ras.annotation.Trivial;
3737
import com.ibm.ws.ffdc.annotation.FFDCIgnore;
3838

39+
import io.openliberty.data.internal.persistence.cdi.DataExtensionProvider;
3940
import jakarta.persistence.EntityManager;
4041
import jakarta.persistence.metamodel.Attribute;
4142
import jakarta.persistence.metamodel.Attribute.PersistentAttributeType;
@@ -65,13 +66,19 @@ public abstract class EntityManagerBuilder implements Runnable {
6566
*/
6667
final ConcurrentHashMap<Class<?>, CompletableFuture<EntityInfo>> entityInfoMap = new ConcurrentHashMap<>();
6768

69+
/**
70+
* OSGi service component that provides the CDI extension for Data.
71+
*/
72+
final DataExtensionProvider provider;
73+
6874
/**
6975
* The class loader for repository classes.
7076
*/
7177
private final ClassLoader repositoryClassLoader;
7278

7379
@Trivial
74-
protected EntityManagerBuilder(ClassLoader repositoryClassLoader) {
80+
protected EntityManagerBuilder(DataExtensionProvider provider, ClassLoader repositoryClassLoader) {
81+
this.provider = provider;
7582
this.repositoryClassLoader = repositoryClassLoader;
7683
}
7784

dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/QueryInfo.java

Lines changed: 163 additions & 29 deletions
Large diffs are not rendered by default.

dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/RepositoryImpl.java

Lines changed: 17 additions & 133 deletions
Large diffs are not rendered by default.

dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/cdi/DataExtension.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager b
204204
EntityManagerFactory emf = instance.get();
205205

206206
if (emBuilder == null)
207-
emBuilder = new PUnitEMBuilder(emf, loader);
207+
emBuilder = new PUnitEMBuilder(emf, loader, provider);
208208
else
209209
throw new UnsupportedOperationException//
210210
("The " + method.getName() + " resource accessor method of the " +
@@ -225,7 +225,7 @@ public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager b
225225
try {
226226
Object resource = InitialContext.doLookup(dataStore);
227227
if (resource instanceof EntityManagerFactory)
228-
emBuilder = new PUnitEMBuilder((EntityManagerFactory) resource, dataStore, loader);
228+
emBuilder = new PUnitEMBuilder((EntityManagerFactory) resource, dataStore, loader, provider);
229229

230230
if (trace && tc.isDebugEnabled())
231231
Tr.debug(this, tc, dataStore + " is the JNDI name for " + resource);
@@ -238,7 +238,7 @@ public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager b
238238
Object resource = InitialContext.doLookup(javaCompName);
239239

240240
if (resource instanceof EntityManagerFactory)
241-
emBuilder = new PUnitEMBuilder((EntityManagerFactory) resource, javaCompName, loader);
241+
emBuilder = new PUnitEMBuilder((EntityManagerFactory) resource, javaCompName, loader, provider);
242242

243243
if (emBuilder != null || resource instanceof DataSource) {
244244
isJNDIName = true;

dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/provider/PUnitEMBuilder.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.ibm.ws.threadContext.ComponentMetaDataAccessorImpl;
2121

2222
import io.openliberty.data.internal.persistence.EntityManagerBuilder;
23+
import io.openliberty.data.internal.persistence.cdi.DataExtensionProvider;
2324
import jakarta.persistence.EntityManager;
2425
import jakarta.persistence.EntityManagerFactory;
2526

@@ -37,8 +38,8 @@ public class PUnitEMBuilder extends EntityManagerBuilder {
3738

3839
private final String persistenceUnitRef;
3940

40-
public PUnitEMBuilder(EntityManagerFactory emf, ClassLoader repositoryClassLoader) {
41-
super(repositoryClassLoader);
41+
public PUnitEMBuilder(EntityManagerFactory emf, ClassLoader repositoryClassLoader, DataExtensionProvider provider) {
42+
super(provider, repositoryClassLoader);
4243
this.emf = emf;
4344
this.persistenceUnitRef = emf.toString();
4445

@@ -52,8 +53,9 @@ public PUnitEMBuilder(EntityManagerFactory emf, ClassLoader repositoryClassLoade
5253
// DataStoreTestApp#DataStoreTestWeb.war, org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl@3708cabf]
5354
}
5455

55-
public PUnitEMBuilder(EntityManagerFactory emf, String persistenceUnitRef, ClassLoader repositoryClassLoader) {
56-
super(repositoryClassLoader);
56+
public PUnitEMBuilder(EntityManagerFactory emf, String persistenceUnitRef,
57+
ClassLoader repositoryClassLoader, DataExtensionProvider provider) {
58+
super(provider, repositoryClassLoader);
5759
this.emf = emf;
5860
this.persistenceUnitRef = persistenceUnitRef;
5961

dev/io.openliberty.data.internal.persistence/src/io/openliberty/data/internal/persistence/service/DBStoreEMBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public class DBStoreEMBuilder extends EntityManagerBuilder {
121121
public DBStoreEMBuilder(String dataStore, boolean isConfigDisplayId, boolean isJNDIName,
122122
AnnotatedType<?> type, ClassLoader repositoryClassLoader,
123123
DataExtensionProvider provider) {
124-
super(repositoryClassLoader);
124+
super(provider, repositoryClassLoader);
125125
final boolean trace = TraceComponent.isAnyTracingEnabled();
126126

127127
ComponentMetaData cData = ComponentMetaDataAccessorImpl.getComponentMetaDataAccessor().getComponentMetaData();

dev/io.openliberty.data.internal_fat/test-applications/DataTestApp/src/test/jakarta/data/web/DataTestServlet.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3592,7 +3592,11 @@ public void testRecordInFromClause() {
35923592
assertEquals(20.98f, receipts.totalOf(2000L), 0.001f);
35933593
assertEquals(15.99f, receipts.totalOf(2001L), 0.001f);
35943594

3595-
receipts.deleteByTotalLessThan(2000.0f);
3595+
assertEquals(true, receipts.addTax(2001L, 0.0813f));
3596+
3597+
assertEquals(17.29f, receipts.totalOf(2001L), 0.001f);
3598+
3599+
assertEquals(2, receipts.removeIfTotalUnder(2000.0f));
35963600
}
35973601

35983602
/**

dev/io.openliberty.data.internal_fat/test-applications/DataTestApp/src/test/jakarta/data/web/Receipts.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
*/
2727
@Repository
2828
public interface Receipts extends CrudRepository<Receipt, Long> {
29+
@Query("UPDATE Receipt SET total = total * (1.0 + :taxRate) WHERE purchaseId = :id")
30+
boolean addTax(long id, float taxRate);
31+
2932
@Query("SELECT COUNT(this)")
3033
long count();
3134

@@ -42,6 +45,9 @@ public interface Receipts extends CrudRepository<Receipt, Long> {
4245

4346
Stream<Receipt> findByPurchaseIdIn(Iterable<Long> ids);
4447

48+
@Query("DELETE FROM Receipt WHERE total < :max")
49+
int removeIfTotalUnder(float max);
50+
4551
@Query("SELECT total FROM Receipt WHERE purchaseId=:id")
4652
float totalOf(long id);
4753
}

dev/io.openliberty.data.internal_fat_jpa/test-applications/DataJPATestApp/src/test/jakarta/data/jpa/web/DataJPATestServlet.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,6 +2458,66 @@ public void testParenthesisInsertionForCursorPagination() {
24582458
assertEquals(false, page3.hasNext());
24592459
}
24602460

2461+
/**
2462+
* Use a repository method that runs a query without specifying an entity type
2463+
* and returns a record entity. The repository must be able to infer the record type
2464+
* to use from the return value and generate the proper select clause so that the
2465+
* generated entity type is converted to the record type.
2466+
*/
2467+
@Test
2468+
public void testRecordQueryInfersSelectClause() {
2469+
2470+
Rebate r1 = new Rebate(10, 10.00, "testRecordEntityInferredFromReturnType-CustomerA", //
2471+
LocalTime.of(15, 40, 0), //
2472+
LocalDate.of(2024, Month.MAY, 1), //
2473+
Rebate.Status.PAID, //
2474+
LocalDateTime.of(2024, Month.MAY, 1, 15, 40, 0), //
2475+
null);
2476+
2477+
Rebate r2 = new Rebate(12, 12.00, "testRecordEntityInferredFromReturnType-CustomerA", //
2478+
LocalTime.of(12, 46, 30), //
2479+
LocalDate.of(2024, Month.APRIL, 5), //
2480+
Rebate.Status.PAID, //
2481+
LocalDateTime.of(2024, Month.MAY, 2, 10, 18, 0), //
2482+
null);
2483+
2484+
Rebate r3 = new Rebate(13, 3.00, "testRecordEntityInferredFromReturnType-CustomerB", //
2485+
LocalTime.of(9, 15, 0), //
2486+
LocalDate.of(2024, Month.MAY, 2), //
2487+
Rebate.Status.PAID, //
2488+
LocalDateTime.of(2024, Month.MAY, 2, 9, 15, 0), //
2489+
null);
2490+
2491+
Rebate r4 = new Rebate(14, 4.00, "testRecordEntityInferredFromReturnType-CustomerA", //
2492+
LocalTime.of(10, 55, 0), //
2493+
LocalDate.of(2024, Month.MAY, 1), //
2494+
Rebate.Status.VERIFIED, //
2495+
LocalDateTime.of(2024, Month.MAY, 2, 14, 27, 45), //
2496+
null);
2497+
2498+
Rebate r5 = new Rebate(15, 5.00, "testRecordEntityInferredFromReturnType-CustomerA", //
2499+
LocalTime.of(17, 50, 0), //
2500+
LocalDate.of(2024, Month.MAY, 1), //
2501+
Rebate.Status.PAID, //
2502+
LocalDateTime.of(2024, Month.MAY, 5, 15, 5, 0), //
2503+
null);
2504+
2505+
Rebate[] all = rebates.addAll(r1, r2, r3, r4, r5);
2506+
2507+
List<Rebate> paid = rebates.paidTo("testRecordEntityInferredFromReturnType-CustomerA");
2508+
2509+
assertEquals(paid.toString(), 3, paid.size());
2510+
Rebate r;
2511+
r = paid.get(0);
2512+
assertEquals(12.0f, r.amount(), 0.001);
2513+
r = paid.get(1);
2514+
assertEquals(10.0f, r.amount(), 0.001);
2515+
r = paid.get(2);
2516+
assertEquals(5.0f, r.amount(), 0.001);
2517+
2518+
rebates.removeAll(all);
2519+
}
2520+
24612521
/**
24622522
* Tests lifecycle methods returning a single record.
24632523
*/

dev/io.openliberty.data.internal_fat_jpa/test-applications/DataJPATestApp/src/test/jakarta/data/jpa/web/Rebates.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import jakarta.data.repository.Delete;
2020
import jakarta.data.repository.Insert;
21+
import jakarta.data.repository.Query;
2122
import jakarta.data.repository.Repository;
2223
import jakarta.data.repository.Save;
2324
import jakarta.data.repository.Update;
@@ -45,6 +46,9 @@ public interface Rebates { // Do not allow this interface to inherit from other
4546
@Update
4647
List<Rebate> modifyMultiple(List<Rebate> r);
4748

49+
@Query("WHERE customerId=?1 AND status=test.jakarta.data.jpa.web.Rebate.Status.PAID ORDER BY amount DESC, id ASC")
50+
List<Rebate> paidTo(String customerId);
51+
4852
@Save
4953
Rebate process(Rebate r);
5054

0 commit comments

Comments
 (0)