← Zur Uebersicht

Component-Mapping: EJB/Java-EE-Konzept -> Spring/Cloud-native-Entsprechung

Diese Tabelle ist der Kern der Migrationsdoku - fuer jedes EJB-/Java-EE-Konzept aus docs/10-ejb-konzepte/ steht hier die konkrete Entsprechung im modernen Reactor, mit Verweis auf die tatsaechliche Klasse auf beiden Seiten.

Legacy (EJB/Java EE) Klasse (Legacy) Modern (Spring) Klasse (Modern)
Stateless Session Bean PolicyManagementBean @Service PolicyManagementService
Bean-Managed Transactions PremiumCalculationBean TransactionTemplate/PlatformTransactionManager PremiumCalculationService
Container-Managed Transactions @TransactionAttribute @Transactional (deklarativ) PolicyManagementService
MDB (Queue, Request/Reply) ClaimIntakeMDB Kafka @KafkaListener ClaimIntakeKafkaListener
JMS-Request/Reply-Client ClaimSubmissionClient ReplyingKafkaTemplate ClaimSubmissionKafkaClient (novaris-claims-modern)
MDB (Topic, Pub/Sub) PolicyDocumentGenerationMDB, CustomerNotificationMDB zwei @KafkaListener-Consumer-Groups PolicyDocumentGenerationListener, CustomerNotificationListener (novaris-notification-modern)
JMS-Topic-Publisher PolicyEventPublisherBean KafkaTemplate KafkaPolicyEventPublisherAdapter
Singleton + Timer Service PolicyRenewalTimerBean @Scheduled + TaskScheduler PolicyRenewalScheduler
Annotationsbasierter Interceptor AuditInterceptor (@Interceptors) Spring AOP @Aspect/@Around AuditAspect
XML-gebundener Interceptor ejb-jar.xml-Binding auf PremiumCalculationBean (kein XML-Pendant - ein einziger, globaler Pointcut-Ausdruck statt zweier Bindungsarten) AuditAspect
Application Exception (rollback=true) PolicyNotFoundException (checked) unchecked RuntimeException, Rollback ist der @Transactional-Default PolicyNotFoundException
Application Exception (rollback=false) UnderwritingRejectedException (checked) unchecked RuntimeException + @Transactional(noRollbackFor=...) UnderwritingRejectedException
Repository als eigener @Stateless-Bean PolicyRepository Spring-Data-JPA-Interface (Singleton-Proxy) PolicyJpaRepository
JNDI-Lookup (@Resource(lookup=...)) JndiLookupHelper, JndiNames Spring-DI + application.yml KafkaTopics (Topic-Namen statt JNDI-Namen)
Local + Remote Interface PolicyManagementLocal/Remote ein REST-Controller bedient beide Faelle PolicyController
Stateful Session Bean PolicyApplicationWizardBean persistierte, per ID adressierte Entity PolicyApplicationDraft + PolicyApplicationDraftService
JAX-WS-Server (SEI) novaris-billing-soap bleibt unveraendert (externer Partner) -
JAX-WS-Client BillingIntegrationBean JaxWsPortProxyFactoryBean SoapBillingIntegrationAdapter + BillingClientConfig
JAAS Custom Login Module + LTPA NovarisLegacyLoginModule Spring Security (OAuth2 Resource Server + Keycloak, seit M6) SecurityConfig
JSF-Portal novaris-policy-web-legacy-jsf REST-API + eigenstaendiges React-SPA (seit M6) PolicyController + novaris-policy-web-modern-spa
WebSphere Liberty + EAR-Deployment novaris-policy-ear Spring-Boot-Fat-Jar + Container-Image spring-boot-maven-plugin
Jenkins EAR-Kopie/Liberty-Deploy ci/scripts/deploy.sh Jenkins Image-Build + oc apply/Helm folgt in M5

Zwei Muster verdienen eine ausfuehrlichere Erklaerung

Stateful Session Bean -> persistierte Draft-Entity (umgesetzt in M2)

PolicyApplicationWizardBean hielt seinen Zustand (Quote -> Underwriting -> Bind) ueber mehrere Aufrufe hinweg im EJB-Container, gebunden an eine Client-Session. Die naheliegende Spring-Entsprechung waere ein @SessionScope-Bean gewesen - das wuerde aber Session-Affinity voraussetzen (derselbe Pod muss jeden Folgeaufruf bedienen), was horizontaler Skalierung auf OpenShift widerspricht. Umgesetzte Loesung: der Wizard-Zustand ist jetzt explizit als Datenbank-Entity (PolicyApplicationDraft, siehe deren ausfuehrlichen Javadoc) persistiert und per generierter ID adressiert statt im Server-Speicher gehalten - jeder Request kann von jedem Pod bedient werden. Das ist ein bewusster Architekturwechsel (nicht nur eine Technologie-Uebersetzung), verifiziert per echtem End-to-End-Lauf des kompletten Wizard-Ablaufs (siehe novaris-policy-core-modern/README.md).

Repository als EJB vs. als Spring-Data-Interface

PolicyRepository musste im Legacy-Original selbst ein @Stateless-Bean sein, ausschliesslich damit der Container einen @PersistenceContext-EntityManager injizieren konnte - "Repository als EJB" ist ein reines Artefakt des Programmiermodells, keine fachliche Notwendigkeit. Spring Data JPA generiert PolicyJpaRepository zur Laufzeit aus einem reinen Interface heraus, als Singleton-Proxy - kein manuelles EntityManager-Handling, keine JPQL-Strings fuer die simplen Faelle (Methodennamen wie findByPolicyNumber werden automatisch in eine Query uebersetzt).

⌂ Cockpit