Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Simplifying J2EE: Patterns that Actually Help

Posted on February 3, 2007 By Luis Fernandez

I walked into a client room where the whiteboard already looked tired. Boxes, arrows, and the usual EJB question marks. The team kept repeating the same wish. Make J2EE simple. Not cute. Just less painful. We pulled the plug on a few heroic ideas, cut the XML sprawl, and shipped faster than anyone expected. The trick was not magic. It was picking a few patterns that pull their weight and ignoring the rest. That day shaped how I approach Java on servers, and it keeps paying off.

Start with wiring. Forget the old Service Locator habit unless you really need it. Use Dependency Injection. With EJB 3 you can inject resources and session beans with annotations. With Spring 2 you get clear wiring, test friendly code, and sane defaults. The point is to push object graphs and configuration out of factories and into the container so your code reads like a story. Keep the container for transactions, security, and pooling. Do not bake those into your classes. A small rule that helps. Inject interfaces, not concrete types, and hide the container behind the edges of your app. That gives you clean unit tests and a smaller mental load.

Draw bold lines around your system. Use a Service Facade at the boundary and keep calls coarse grained. If the call goes remote, send a DTO and avoid chatty back and forth. Inside the same JVM, skip DTOs and pass domain objects or simple values. When work does not need a reply right away, queue it. JMS plus a Message Driven Bean or a Spring message listener gives you a solid worker model. Make messages idempotent by carrying a business key and checking it before you update state. If you touch a slow partner system, wrap it with an adapter and keep your core model clean. That boundary is where retries, timeouts, and logging belong, not scattered through the codebase.

On data, pick one clear path. JPA with an EntityManager is the sane default, whether you run on GlassFish, JBoss, or Tomcat with Spring and Hibernate. Use a thin DAO or Repository that speaks in terms of your domain, not in terms of rows. Keep queries close to the aggregate that owns them and prefer named queries for reuse and readability. Let the container or Spring drive transaction management with annotations and be explicit about boundaries. Lazy loading is fine but know where views or services end so you do not trigger database access in the wrong place. If you must keep the session open for a view, do it knowingly and document why. For read heavy screens, add caching at the query level and expire by event, not by wishful thinking.

The web tier loves to grow horns, so keep it small. A simple MVC with a filter as the front door, a controller that maps intents, and actions that call services is plenty. Struts is everywhere, and Spring MVC feels lighter while keeping a clean model. JSF is getting better, especially with Facelets, but it can feel heavy if your team is not on the same page. Use validation at the edges with clear messages and never let controllers talk to the database. If you bring Ajax into the room, treat it as a view concern and keep URLs stable. Map exceptions to user friendly pages, log once at the boundary, and leave the stack trace out of the browser. Convention beats XML walls every time.

Tooling should help and then get out of the way. Maven 2 or Ant with Ivy can manage dependencies without turning builds into puzzles. Keep one command that runs tests and packages your app. JUnit 4 and EasyMock make quick tests natural, and if you are running a server, wire up a few story tests through the facade to catch wiring mistakes. A small continuous integration box, be it CruiseControl or Hudson, gives you a bell that rings when a commit breaks the happy path. The point is not to chase tools. The point is to make feedback quick so patterns become habits and not binders on a shelf.

Quick hits that save weekends. Keep stateless session beans for services that just need scale and a clean transaction. Use value objects that are small and immutable for money, dates, and ids, so your equals and hash rules do not surprise you. Push cross cutting stuff into interceptors or aspects, but only the parts you can explain on a napkin. When the database model screams in circles, pick Transaction Script for simple flows and reach for a Domain Model only when rules deserve it. Review logs with a real plan. One line per event, a fixed format, and correlation ids where it matters. Future you will say thanks.

Java just shipped a new release of the platform and EJB 3 arrived with annotations that feel human. Spring keeps moving fast and the web crowd is excited about jQuery and other Ajax toys. The noise is loud. The cure is boring. Pick a few patterns that lower friction and teach them to the whole team. Dependency Injection for wiring. Service Facade at the edges. JPA for persistence with clear transactions. A lean MVC for the web. That small set makes J2EE feel lighter, projects ship, and whiteboards stay clean enough to draw tomorrow.

General Software Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes