DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Mastering Persistence: Why the Persistence Layer Is Crucial for Modern Java Applications
  • Exploring Seamless Integration: Jakarta Data and Jakarta Persistence in Jakarta EE 11 With Open Liberty
  • Data Persistence: Keeping Data Safe in an Ever-Changing Digital World
  • Architecture and Code Design, Pt. 2: Polyglot Persistence Insights To Use Today and in the Upcoming Years

Trending

  • What Is Good Database Design?
  • Vector Database: A Beginner's Guide
  • The Promise of Personal Data for Better Living
  • Understanding Git
  1. DZone
  2. Data Engineering
  3. Databases
  4. About Transparent Persistence

About Transparent Persistence

Here's an overview of transparent persistence in action and why it can be an invaluable concept. Go through the steps of setting up your own persistent ORM.

Enrique Molinari user avatar by
Enrique Molinari
·
Aug. 23, 16 · Tutorial
Like (3)
Save
Tweet
Share
4.36K Views

Join the DZone community and get the full member experience.

Join For Free

When you are developing in the object-oriented paradigm and you have to persist your objects via relational storage, there are, basically, two ways of doing it: using an ORM or using the database connectivity API that the language provides. What is the factor when choosing between one or the other?

Talking now in terms of the Java programming language, what makes you choose Hibernate over JDBC? Is it their Criteria API? HQL?  

I personally use Hibernate because of their Transparent Persistence support. That is the real beauty. Let me explain what I mean.

The goal of an ORM is to let you design your application without worrying about a persistent mechanism. Design your domain model, implement it and test it, and just persist it on volatile memory. The ORM tool, after it's configured, will take care of persisting your objects in a persistent storage.

Let's illustrate the previous sentence with an example using a common problem domain: Organizations. Let's model Departments and Employees, where departments have members that are their employees. I would write the following two classes (simplified):

public class Department {
    private String name;
    private Collection employees = new ArrayList<>();

    public Department(String name) {
        this.name = name;
    }

    public void addEmployee(Employee m) {
        employees.add(m);
    }

    public int totalEmployees() {
        return employees.size();
    }
}

public class Employee {
    private float salary;
    private String name;

    public Employee(String name, float salary) {
        this.name = name;
        this.salary = salary;
    }

    public String name() {
        return this.name;
    }

    public float salary() {
        return this.salary;
    }
}


And a test to cover that piece of functionality:

@Test
public void a_new_employee_is_added_then_it_increments_the_total() {
    Department sales = new Department("Sales");
    Employee jorge = new Employee("Jorge Dalmiro", 1239f);
    sales.addEmployee(jorge);
    Assert.assertEquals(1, sales.totalEmployees());
}


An ORM like Hibernate will let you write something like the test above and make the relation between the employee jorge and the sales department persistent — isn't that great?

You may be asking, "I don't have to deal with the save or store method of the ORM API? I don't have to write any SQL statement?" No! you have to just write code like this:

department1.addEmployee(new Employee("José", 10503f));


Then José will be persisted and be part of department1.

The real beauty of an ORM is the transparent persistence that provides, which will let you write plain Java objects and make them persistent with little work.

Transparent Persistence

To understand how transparent persistence works, we have to understand two main concepts. The first one is called Persistence Context. The Persistence Context is the place used by the ORM to keep track of the changes of your instances in order to persist them at a later point. In the Java Persistence API, this context is managed by the javax.persistence.EntityManager class. Each Java Object in a persistence context will have one of these states:

  • New, or transient: The object has just been instantiated and is not associated with a persistence context. It has no persistent representation in the persistent storage.
  • Persistent: The object is associated with a persistence context and has representation in the persistent storage.

  • Detached: The object is no longer associated with a persistence context (usually because the persistence context was closed).

  • Removed: The object is associated with a persistence context. However, it is scheduled for removal from the persistent storage.

The other important concept is called Persistence by Reachability, which states that any transient object that gets related to a persistent object will become persistent, too.

These two concepts are implemented in an ORM to make possible so-called Transparent Persistence.

Let's put these concepts in code.

    EntityManager em = //obtain the EntityManger instance
    EntityTransaction tx = //obtain the EntityTransaction instance

    try {
        tx = em.getTransaction();
        tx.begin();

        Department dept1 = em.find(Department.class, "department1");
        dept1.addEmployee(new Employee("José", 10503f));

        tx.commit();
    } catch (Exception e) {
        if (tx != null) {
            tx.rollback();
        }
        throw new RuntimeException(e);
    } finally {
        em.close();
    }


On line 8, I'm getting the Department department1 from the persistent storage and, on line 9, just appending a new employee to it. Due to the fact that department1 is in the persistent state, by reachability  the transient instance of Employee (José) will be persisted and attached to the department.

Let's write something a bit richer. Suppose now that I have the following new requirements. Each department gains 5 points each time a woman joins them and 3 points for men. Also, each department loses 5 points when an employee leaves them. I would change the Department class in the following way:

public class Department {
    ...
    private int points;

    public void addEmployee(Employee e) {
        points += e.points();
        employees.add(e);
    }

    public void removeEmployee(Employee e) {
        points -= 5;
        employees.remove(e);
    }
    ...
}


Now, if I add an employee to a department:

    //start persistence context
    ...
    Department dept1 = // retrieving from the storage
    dept1.addEmployee(new Employee("Julio", 6205f));
    ...
    //close end of persistence context


In addition to persisting the new Employee and the relation with the department, it will also persist the new points obtained by adding employees to the department. It will be done by executing two SQL statements wrapped in a transaction. Something like:

insert into employees values("Julio", 6205f, "department1");
update departments set points = ? where id = "department1";


That was transparent right? You can visualize all the work done by the ORM for you. This means that you can focus the effort on making a good Object Domain Model (and by good I mean with business logic inside and not an anemic model), test it on memory, get a high test coverage, and let the ORM take care of the persistence.

The support of Transparent Persistence is what makes Hibernate (and others) an invaluable tool.

Persistence (computer science)

Opinions expressed by DZone contributors are their own.

Related

  • Mastering Persistence: Why the Persistence Layer Is Crucial for Modern Java Applications
  • Exploring Seamless Integration: Jakarta Data and Jakarta Persistence in Jakarta EE 11 With Open Liberty
  • Data Persistence: Keeping Data Safe in an Ever-Changing Digital World
  • Architecture and Code Design, Pt. 2: Polyglot Persistence Insights To Use Today and in the Upcoming Years

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: