diff --git a/docs/modules/ROOT/pages/reference/extensions/jpa.adoc b/docs/modules/ROOT/pages/reference/extensions/jpa.adoc
index 0b55384217b4..f5af553fd8ef 100644
--- a/docs/modules/ROOT/pages/reference/extensions/jpa.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/jpa.adoc
@@ -50,5 +50,32 @@ endif::[]
The extension leverages https://quarkus.io/guides/hibernate-orm[Quarkus Hibernate ORM] to provide the JPA implementation via Hibernate.
-Refer to the https://quarkus.io/guides/hibernate-orm[Quarkus Hibernate ORM] documentation to see how to configure Hibernate and your datasource,
+Refer to the https://quarkus.io/guides/hibernate-orm[Quarkus Hibernate ORM] documentation to see how to configure Hibernate and your datasource.
+
+Also, it leverages https://quarkus.io/guides/transaction#programmatic-approach[Quarkus TX API] to provide `TransactionStrategy` implementation.
+
+When a single persistence unit is used, the Camel Quarkus JPA extension will automatically configure the JPA component with a
+`EntityManagerFactory` and `TransactionStrategy`.
+
+[id="extensions-jpa-configuration-configuring-jpamessageidrepository"]
+=== Configuring JpaMessageIdRepository
+It needs to use `EntityManagerFactory` and `TransactionStrategy` from the CDI container to configure the `JpaMessageIdRepository`:
+[source, java]
+----
+@Inject
+EntityManagerFactory entityManagerFactory;
+
+@Inject
+TransactionStrategy transactionStrategy;
+
+from("direct:idempotent")
+ .idempotentConsumer(
+ header("messageId"),
+ new JpaMessageIdRepository(entityManagerFactory, transactionStrategy, "idempotentProcessor"));
+----
+
+[NOTE]
+====
+Since it excludes the `spring-orm` dependency, some options such as `sharedEntityManager`, `transactionManager` are not supported.
+====
diff --git a/extensions/jpa/deployment/pom.xml b/extensions/jpa/deployment/pom.xml
index 3738c46d17e8..445540193ce2 100644
--- a/extensions/jpa/deployment/pom.xml
+++ b/extensions/jpa/deployment/pom.xml
@@ -38,10 +38,6 @@
org.apache.camel.quarkus
camel-quarkus-core-deployment
-
- org.apache.camel.quarkus
- camel-quarkus-support-spring-deployment
-
org.apache.camel.quarkus
camel-quarkus-jpa
diff --git a/extensions/jpa/deployment/src/main/java/org/apache/camel/quarkus/component/jpa/deployment/JpaProcessor.java b/extensions/jpa/deployment/src/main/java/org/apache/camel/quarkus/component/jpa/deployment/JpaProcessor.java
index 6d5364145680..adfc8405b81e 100644
--- a/extensions/jpa/deployment/src/main/java/org/apache/camel/quarkus/component/jpa/deployment/JpaProcessor.java
+++ b/extensions/jpa/deployment/src/main/java/org/apache/camel/quarkus/component/jpa/deployment/JpaProcessor.java
@@ -16,8 +16,16 @@
*/
package org.apache.camel.quarkus.component.jpa.deployment;
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
+import org.apache.camel.component.jpa.JpaComponent;
+import org.apache.camel.quarkus.component.jpa.CamelJpaProducer;
+import org.apache.camel.quarkus.component.jpa.CamelJpaRecorder;
+import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeBeanBuildItem;
class JpaProcessor {
@@ -27,4 +35,19 @@ class JpaProcessor {
FeatureBuildItem feature() {
return new FeatureBuildItem(FEATURE);
}
+
+ @Record(ExecutionTime.RUNTIME_INIT)
+ @BuildStep
+ void configureJpaComponentBean(
+ BuildProducer additionalBeans,
+ BuildProducer camelRuntimeBean,
+ CamelJpaRecorder recorder) {
+ additionalBeans.produce(new AdditionalBeanBuildItem(CamelJpaProducer.class));
+
+ camelRuntimeBean.produce(
+ new CamelRuntimeBeanBuildItem(
+ "jpa",
+ JpaComponent.class.getName(),
+ recorder.createJpaComponent()));
+ }
}
diff --git a/extensions/jpa/runtime/pom.xml b/extensions/jpa/runtime/pom.xml
index 1a8c05a9f790..7cb1dc7a3310 100644
--- a/extensions/jpa/runtime/pom.xml
+++ b/extensions/jpa/runtime/pom.xml
@@ -36,6 +36,11 @@
+
+ org.graalvm.sdk
+ graal-sdk
+ provided
+
io.quarkus
quarkus-hibernate-orm
@@ -44,19 +49,10 @@
org.apache.camel.quarkus
camel-quarkus-core
-
- org.apache.camel.quarkus
- camel-quarkus-support-spring
-
org.apache.camel
camel-jpa
-
-
- org.springframework
- spring-tx
-
diff --git a/extensions/jpa/runtime/src/main/doc/configuration.adoc b/extensions/jpa/runtime/src/main/doc/configuration.adoc
index f398236b25fa..0be017ccf153 100644
--- a/extensions/jpa/runtime/src/main/doc/configuration.adoc
+++ b/extensions/jpa/runtime/src/main/doc/configuration.adoc
@@ -1,3 +1,29 @@
The extension leverages https://quarkus.io/guides/hibernate-orm[Quarkus Hibernate ORM] to provide the JPA implementation via Hibernate.
-Refer to the https://quarkus.io/guides/hibernate-orm[Quarkus Hibernate ORM] documentation to see how to configure Hibernate and your datasource,
+Refer to the https://quarkus.io/guides/hibernate-orm[Quarkus Hibernate ORM] documentation to see how to configure Hibernate and your datasource.
+
+Also, it leverages https://quarkus.io/guides/transaction#programmatic-approach[Quarkus TX API] to provide `TransactionStrategy` implementation.
+
+When a single persistence unit is used, the Camel Quarkus JPA extension will automatically configure the JPA component with a
+`EntityManagerFactory` and `TransactionStrategy`.
+
+=== Configuring JpaMessageIdRepository
+It needs to use `EntityManagerFactory` and `TransactionStrategy` from the CDI container to configure the `JpaMessageIdRepository`:
+[source, java]
+----
+@Inject
+EntityManagerFactory entityManagerFactory;
+
+@Inject
+TransactionStrategy transactionStrategy;
+
+from("direct:idempotent")
+ .idempotentConsumer(
+ header("messageId"),
+ new JpaMessageIdRepository(entityManagerFactory, transactionStrategy, "idempotentProcessor"));
+----
+
+[NOTE]
+====
+Since it excludes the `spring-orm` dependency, some options such as `sharedEntityManager`, `transactionManager` are not supported.
+====
diff --git a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaProducer.java b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaProducer.java
new file mode 100644
index 000000000000..25ffd6e2c7b0
--- /dev/null
+++ b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaProducer.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.jpa;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.Dependent;
+import jakarta.enterprise.inject.Produces;
+import org.apache.camel.component.jpa.TransactionStrategy;
+
+@Dependent
+public class CamelJpaProducer {
+ @Produces
+ @ApplicationScoped
+ public TransactionStrategy quarkusTransactionStrategy() {
+ return new QuarkusTransactionStrategy();
+ }
+}
diff --git a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
new file mode 100644
index 000000000000..658d5424ee06
--- /dev/null
+++ b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.jpa;
+
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.Recorder;
+import org.apache.camel.component.jpa.JpaComponent;
+
+@Recorder
+public class CamelJpaRecorder {
+
+ public RuntimeValue createJpaComponent() {
+ JpaComponent component = new JpaComponent();
+ component.setTransactionStrategy(new QuarkusTransactionStrategy());
+ return new RuntimeValue<>(component);
+ }
+}
diff --git a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/QuarkusTransactionStrategy.java b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/QuarkusTransactionStrategy.java
new file mode 100644
index 000000000000..755968491acc
--- /dev/null
+++ b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/QuarkusTransactionStrategy.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.quarkus.component.jpa;
+
+import io.quarkus.narayana.jta.QuarkusTransaction;
+import io.quarkus.narayana.jta.RunOptions;
+import org.apache.camel.component.jpa.TransactionStrategy;
+
+import static io.quarkus.narayana.jta.QuarkusTransaction.runOptions;
+
+public class QuarkusTransactionStrategy implements TransactionStrategy {
+ @Override
+ public void executeInTransaction(Runnable runnable) {
+ QuarkusTransaction.run(runOptions().semantic(RunOptions.Semantic.JOIN_EXISTING), runnable);
+ }
+}
diff --git a/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/graal/JpaSubstitution.java b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/graal/JpaSubstitution.java
new file mode 100644
index 000000000000..b7672a1fa985
--- /dev/null
+++ b/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/graal/JpaSubstitution.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.quarkus.component.jpa.graal;
+
+import com.oracle.svm.core.annotate.Alias;
+import com.oracle.svm.core.annotate.Delete;
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+import jakarta.persistence.EntityManagerFactory;
+import org.apache.camel.component.jpa.DefaultTransactionStrategy;
+import org.apache.camel.component.jpa.JpaComponent;
+import org.apache.camel.component.jpa.JpaEndpoint;
+import org.apache.camel.component.jpa.TransactionStrategy;
+
+final public class JpaSubstitution {
+}
+
+@TargetClass(JpaEndpoint.class)
+final class JpaEndpointSubstitution {
+ @Alias
+ private TransactionStrategy transactionStrategy;
+
+ @Substitute
+ protected EntityManagerFactory createEntityManagerFactory() {
+ throw new UnsupportedOperationException("createEntityManagerFactory is not supported");
+ }
+
+ @Substitute
+ public TransactionStrategy getTransactionStrategy() {
+ return transactionStrategy;
+ }
+}
+
+@TargetClass(JpaComponent.class)
+final class JpaComponentSubstitution {
+ @Substitute
+ private void createTransactionStrategy() {
+ }
+}
+
+@TargetClass(DefaultTransactionStrategy.class)
+@Delete
+final class DefaultTransactionStrategySubstitution {
+}
diff --git a/extensions/jpa/runtime/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java b/extensions/jpa/runtime/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java
new file mode 100644
index 000000000000..07f90799be99
--- /dev/null
+++ b/extensions/jpa/runtime/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.orm.jpa;
+
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.EntityManagerFactory;
+
+public abstract class SharedEntityManagerCreator {
+ public static EntityManager createSharedEntityManager(EntityManagerFactory emf) {
+ throw new UnsupportedOperationException("createSharedEntityManager is not supported");
+ }
+}
diff --git a/integration-tests/jpa/src/main/java/org/apache/camel/quarkus/component/jpa/it/JpaRoute.java b/integration-tests/jpa/src/main/java/org/apache/camel/quarkus/component/jpa/it/JpaRoute.java
index 6f3bf380f28c..737dcd7bd101 100644
--- a/integration-tests/jpa/src/main/java/org/apache/camel/quarkus/component/jpa/it/JpaRoute.java
+++ b/integration-tests/jpa/src/main/java/org/apache/camel/quarkus/component/jpa/it/JpaRoute.java
@@ -22,16 +22,19 @@
import jakarta.inject.Inject;
import jakarta.persistence.EntityManagerFactory;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.jpa.TransactionStrategy;
+import org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository;
import org.apache.camel.quarkus.component.jpa.it.model.Fruit;
-import static org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository.jpaMessageIdRepository;
-
@ApplicationScoped
public class JpaRoute extends RouteBuilder {
@Inject
EntityManagerFactory entityManagerFactory;
+ @Inject
+ TransactionStrategy transactionStrategy;
+
@Override
public void configure() throws Exception {
String jpaEndpoint = "jpa:" + Fruit.class.getName();
@@ -72,7 +75,7 @@ public void configure() throws Exception {
from("direct:idempotent")
.idempotentConsumer(
header("messageId"),
- jpaMessageIdRepository(entityManagerFactory, "idempotentProcessor"))
+ new JpaMessageIdRepository(entityManagerFactory, transactionStrategy, "idempotentProcessor"))
.log("Consumes messageId: ${header.messageId}")
.to("mock:idempotent");
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index 9d0214dbcc13..d4b4b6dba93d 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -1578,6 +1578,10 @@
org.apache.camel
camel-spring
+
+ org.springframework
+ spring-orm
+
diff --git a/poms/bom/src/main/generated/flattened-full-pom.xml b/poms/bom/src/main/generated/flattened-full-pom.xml
index 69b7d4b8c77d..2daf86885b92 100644
--- a/poms/bom/src/main/generated/flattened-full-pom.xml
+++ b/poms/bom/src/main/generated/flattened-full-pom.xml
@@ -1516,6 +1516,10 @@
org.apache.camel
camel-spring
+
+ org.springframework
+ spring-orm
+
diff --git a/poms/bom/src/main/generated/flattened-reduced-pom.xml b/poms/bom/src/main/generated/flattened-reduced-pom.xml
index 05a4cce50d9f..f9cfca0b7a6a 100644
--- a/poms/bom/src/main/generated/flattened-reduced-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-pom.xml
@@ -1516,6 +1516,10 @@
org.apache.camel
camel-spring
+
+ org.springframework
+ spring-orm
+
@@ -6569,21 +6573,6 @@
-
- org.springframework
- spring-orm
- 6.0.11
-
-
- org.springframework
- spring-beans
-
-
- org.springframework
- spring-core
-
-
-
org.springframework
spring-tx
diff --git a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
index 4a08d4801d54..a40e3abfff39 100644
--- a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
@@ -1516,6 +1516,10 @@
org.apache.camel
camel-spring
+
+ org.springframework
+ spring-orm
+
@@ -6569,21 +6573,6 @@
-
- org.springframework
- spring-orm
- 6.0.11
-
-
- org.springframework
- spring-beans
-
-
- org.springframework
- spring-core
-
-
-
org.springframework
spring-tx