diff --git a/metadata-mapping/README.md b/metadata-mapping/README.md index e51fc46c7..3a66c426b 100644 --- a/metadata-mapping/README.md +++ b/metadata-mapping/README.md @@ -1,14 +1,17 @@ --- title: Metadata Mapping -category: Architectural +category: Data access language: en tag: - - Data access + - Decoupling + - Enterprise patterns + - Object mapping + - Persistence --- ## Intent -Holds details of object-relational mapping in the metadata. +Metadata Mapping is designed to manage the mapping between database records and objects in a way that keeps the database schema and object model decoupled and manageable. ## Explanation @@ -151,7 +154,7 @@ public class UserService { } // other CRUDs -> - ... + // ... public void close() { HibernateUtil.shutdown(); @@ -161,19 +164,39 @@ public class UserService { ## Class diagram -![metamapping](./etc/metamapping.png) +![Metadata Mapping](./etc/metamapping.png) ## Applicability -Use the Metadata Mapping when: +Use this pattern when you need to bridge the gap between an object-oriented domain model and a relational database, without hard-coding database queries into the domain logic. -- you want reduce the amount of work needed to handle database mapping. +## Known Uses -## Known uses +* Object-Relational Mapping (ORM) frameworks like Hibernate, JPA, EclipseLink and MyBatis. +* Mapping database rows to domain objects in enterprise applications. -[Hibernate](https://hibernate.org/), [EclipseLink](https://www.eclipse.org/eclipselink/), [MyBatis](https://blog.mybatis.org/)...... +## Consequences + +Benefits: + +* Decouples object model and database schema, allowing independent evolution. +* Reduces boilerplate code associated with data access. +* Centralizes mapping logic, making changes more manageable. + +Trade-offs: + +* Adds complexity due to an additional layer of abstraction. +* Can impact performance if not properly optimized. + +## Related Patterns + +* [Data Mapper](https://java-design-patterns.com/patterns/data-mapper/): Metadata Mapping is often used within the broader Data Mapper pattern to facilitate the mapping process. +* Active Record: Differently from Active Record, Metadata Mapping separates the data access logic from the domain entities. +* [Repository](https://java-design-patterns.com/patterns/repository/): Works well with the Repository pattern by abstracting data access further, allowing more complex domain logic to be cleanly separated from data mapping. ## Credits -- [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) - +* [J2EE Design Patterns](https://amzn.to/4dpzgmx) +* [Java Persistence with Hibernate](https://amzn.to/44tP1ox) +* [Patterns of Enterprise Application Architecture](https://amzn.to/3WfKBPR) +* [Pro JPA 2: Mastering the Java Persistence API](https://amzn.to/4b7UoMC) diff --git a/metadata-mapping/src/main/java/com/iluwatar/metamapping/App.java b/metadata-mapping/src/main/java/com/iluwatar/metamapping/App.java index 0bc79f96f..8d4d7ee83 100644 --- a/metadata-mapping/src/main/java/com/iluwatar/metamapping/App.java +++ b/metadata-mapping/src/main/java/com/iluwatar/metamapping/App.java @@ -56,9 +56,8 @@ public class App { * Program entry point. * * @param args command line args. - * @throws Exception if any error occurs. */ - public static void main(String[] args) throws Exception { + public static void main(String[] args) { // get service var userService = new UserService(); // use create service to add users diff --git a/metadata-mapping/src/main/java/com/iluwatar/metamapping/service/UserService.java b/metadata-mapping/src/main/java/com/iluwatar/metamapping/service/UserService.java index b44c461c6..cd731f8d0 100644 --- a/metadata-mapping/src/main/java/com/iluwatar/metamapping/service/UserService.java +++ b/metadata-mapping/src/main/java/com/iluwatar/metamapping/service/UserService.java @@ -49,8 +49,8 @@ public class UserService { try (var session = factory.openSession()) { var tx = session.beginTransaction(); List userIter = session.createQuery("FROM User").list(); - for (var iterator = userIter.iterator(); iterator.hasNext();) { - users.add(iterator.next()); + for (User user : userIter) { + users.add(user); } tx.commit(); } catch (HibernateException e) { diff --git a/metadata-mapping/src/main/java/com/iluwatar/metamapping/utils/HibernateUtil.java b/metadata-mapping/src/main/java/com/iluwatar/metamapping/utils/HibernateUtil.java index 40159d4a2..68d8b4485 100644 --- a/metadata-mapping/src/main/java/com/iluwatar/metamapping/utils/HibernateUtil.java +++ b/metadata-mapping/src/main/java/com/iluwatar/metamapping/utils/HibernateUtil.java @@ -24,6 +24,7 @@ */ package com.iluwatar.metamapping.utils; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; @@ -34,6 +35,7 @@ import org.hibernate.cfg.Configuration; @Slf4j public class HibernateUtil { + @Getter private static final SessionFactory sessionFactory = buildSessionFactory(); /** @@ -50,14 +52,6 @@ public class HibernateUtil { return new Configuration().configure().buildSessionFactory(); } - /** - * Get session factory. - * @return session factory - */ - public static SessionFactory getSessionFactory() { - return sessionFactory; - } - /** * Close session factory. */ diff --git a/metadata-mapping/src/test/java/com/iluwatar/metamapping/AppTest.java b/metadata-mapping/src/test/java/com/iluwatar/metamapping/AppTest.java index 6697296f7..37ba2e09f 100644 --- a/metadata-mapping/src/test/java/com/iluwatar/metamapping/AppTest.java +++ b/metadata-mapping/src/test/java/com/iluwatar/metamapping/AppTest.java @@ -33,7 +33,6 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; class AppTest { /** * Issue: Add at least one assertion to this test case. - * * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} * throws an exception. */