# Active record pattern

> Mediated Wiki article. Canonical URL: https://mediated.wiki/source/Active_record_pattern
> Markdown URL: https://mediated.wiki/source/Active_record_pattern.md
> Source: https://en.wikipedia.org/wiki/Active_record_pattern
> Source revision: 1338854499
> License: Creative Commons Attribution-ShareAlike 4.0 International (https://creativecommons.org/licenses/by-sa/4.0/)

Concept in software engineering

In [software engineering](/source/Software_engineering), the **active record pattern** is an [architectural pattern](/source/Architectural_pattern_(computer_science)). It is found in software that stores in-memory object data in [relational databases](/source/Relational_database). It was named by [Martin Fowler](/source/Martin_Fowler_(software_engineer)) in his 2003 book *Patterns of Enterprise Application Architecture*.[1][2] The interface of an object conforming to this pattern would include functions such as Insert, Update, and Delete, plus properties that correspond more or less directly to the columns in the underlying database table.

The Active Record pattern is a [Data Access Layer](/source/Data_access_layer) that performs bidirectional transfer of data between a persistent data store (often a [relational database](/source/Relational_database)) and an in-memory data representation (the domain layer). A [database table](/source/Database_table) or [view](/source/View_(database)) is wrapped into a [class](/source/Class_(computer_science)). Thus, an [object](/source/Object_(computer_science)) instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save. Any object loaded gets its information from the database. When an object is updated, the corresponding row in the table is also updated. The wrapper class implements [accessor](/source/Accessor) [methods](/source/Method_(computer_programming)) or properties for each column in the table or view.

This pattern is commonly used by object persistence tools and in [object–relational mapping](/source/Object%E2%80%93relational_mapping) (ORM). Typically, [foreign key](/source/Foreign_key) relationships will be exposed as an object instance of the appropriate type via a property.

## Implementations

Implementations of the concept can be found in various [frameworks](/source/Software_framework) for many programming environments. For example, if there is a table parts in a database with columns name (string type) and price (number type), and the Active Record pattern is implemented in the class Part, the pseudo-code

Part part = new Part("Sample part", 123.45);

will create a new row in the parts table with the given values, and is roughly equivalent to the [SQL](/source/SQL) command

INSERT INTO parts (name, price) VALUES ('Sample part', 123.45);

Conversely, the class can be used to query the database:

Part b = parts.stream()
    .filter(p -> "gearbox".equals(p.getName()))
    .findFirst()
    .orElse(null);

This will find a new Part object based on the first matching row from the parts table whose name column has the value "gearbox". The SQL command used might be similar to the following, depending on the SQL implementation details of the database:

SELECT * FROM parts WHERE name = 'gearbox' LIMIT 1; -- MySQL or PostgreSQL

Various libraries implement an active record pattern framework, such as [POCO C++ Libraries](/source/POCO_C%2B%2B_Libraries) in library Poco::ActiveRecord.[3]

## Example

This is a simple example of an active record object User, in [Java](/source/Java_(programming_language)). Here the User class is both the model and [data access object](/source/Data_access_object) and provides save(), find(), and delete() methods.

package org.wikipedia.examples;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class User {
    private int id;
    private String name;
    private String email;

    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void save() {
        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password")) {
            if (this.id == 0) {
                String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
                try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
                    stmt.setString(1, this.name);
                    stmt.setString(2, this.email);
                    stmt.executeUpdate();
                    ResultSet rs = stmt.getGeneratedKeys();
                    if (rs.next()) {
                        this.id = rs.getInt(1);
                    }
                }
            } else {
                String sql = "UPDATE users SET name = ?, email = ? WHERE id = ?";
                try (PreparedStatement stmt = conn.prepareStatement(sql)) {
                    stmt.setString(1, this.name);
                    stmt.setString(2, this.email);
                    stmt.setInt(3, this.id);
                    stmt.executeUpdate();
                }
            }
        } catch (SQLException e) {
            System.err.printf("A SQLException occurred: %s%n", e.getMessage());
            e.printStackTrace();
        }
    }

    public static User find(int id) {
        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password")) {
            String sql = "SELECT * FROM users WHERE id = ?";
            try (PreparedStatement stmt = conn.prepareStatement(sql)) {
                stmt.setInt(1, id);
                ResultSet rs = stmt.executeQuery();
                if (rs.next()) {
                    User user = new User(rs.getString("name"), rs.getString("email"));
                    user.setId(rs.getInt("id"));
                    return user;
                }
            }
        } catch (SQLException e) {
            System.err.printf("A SQLException occurred: %s%n", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    public void delete() {
        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password")) {
            String sql = "DELETE FROM users WHERE id = ?";
            try (PreparedStatement stmt = conn.prepareStatement(sql)) {
                stmt.setInt(1, this.id);
                stmt.executeUpdate();
            }
        } catch (SQLException e) {
            System.err.printf("A SQLException occurred: %s%n", e.getMessage());
            e.printStackTrace();
        }
    }
}

## Criticism

### Single responsibility principle and separation of concerns

Another critique of the active record pattern is that, due to the strong coupling of database interaction and application logic, an active record object does not follow the [single responsibility principle](/source/Single_responsibility_principle) and [separation of concerns](/source/Separation_of_concerns). This is opposed to [multitier architecture](/source/Multitier_architecture), which properly addresses these practices.[*[citation needed](https://en.wikipedia.org/wiki/Wikipedia:Citation_needed)*][*[clarification needed](https://en.wikipedia.org/wiki/Wikipedia:Please_clarify)*] Because of this, the active record pattern is best and most often employed in simple applications that are all forms-over-data with [CRUD](/source/Create%2C_read%2C_update_and_delete) functionality, or only as one part of an architecture.[*[citation needed](https://en.wikipedia.org/wiki/Wikipedia:Citation_needed)*] Typically that part is data access and why several ORMs implement the active record pattern.

## See also

- [Business object](/source/Business_object) – Entity within a multi-tiered software application

- [CRUD](/source/Create%2C_read%2C_update_and_delete) – Basic operations of a computer database

- [Data mapper pattern](/source/Data_mapper_pattern) – Architectural pattern in software engineering

- [Object–relational mapping](/source/Object%E2%80%93relational_mapping) – Programming technique

## References

1. **[^](#cite_ref-1)** [P of EAA Catalog - Active Record](https://martinfowler.com/eaaCatalog/activeRecord.html)

1. **[^](#cite_ref-2)** Fowler, Martin (2003). [*Patterns of enterprise application architecture*](https://books.google.com/books?id=FyWZt5DdvFkC&q=active+record&pg=PT187). Addison-Wesley. [ISBN](/source/ISBN_(identifier)) [978-0-321-12742-6](https://en.wikipedia.org/wiki/Special:BookSources/978-0-321-12742-6).

1. **[^](#cite_ref-3)** ["Namespace Poco::ActiveRecord"](https://docs.pocoproject.org/current/Poco.ActiveRecord.html). *docs.pocoproject.org*. POCO Project. Retrieved 18 October 2025.

v t e Software design patterns Gang of Four patterns Creational Abstract factory Builder Factory method Prototype Singleton Structural Adapter Bridge Composite Decorator Facade Flyweight Proxy Behavioral Chain of responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template method Visitor Concurrency patterns Active object Balking Binding properties Double-checked locking Event-based asynchronous Guarded suspension Join Lock Monitor Proactor Reactor Read–write lock Scheduler Scheduled-task pattern Semaphore Thread pool Thread-local storage Architectural patterns Front controller Interceptor MVC MVP MVVM ADR ECS n-tier Specification Publish–subscribe Naked objects Service locator Active record Identity map Data access object (DAO) Data transfer object (DTO) Inversion of control Model 2 Broker Other patterns Blackboard Business delegate Composite entity Composition over inheritance Dependency injection Guard clause Intercepting filter Lazy loading Mock object Null object Object pool Servant Twin Type tunnel Method chaining Delegation Books Design Patterns Enterprise Integration Patterns People Christopher Alexander Erich Gamma Ralph Johnson John Vlissides Grady Booch Kent Beck Ward Cunningham Martin Fowler Robert Martin Jim Coplien Douglas Schmidt Linda Rising Communities The Hillside Group Portland Pattern Repository See also Anti-pattern Architectural pattern

---
Adapted from the Wikipedia article [Active record pattern](https://en.wikipedia.org/wiki/Active_record_pattern) by Wikipedia contributors ([contributor history](https://en.wikipedia.org/wiki/Active_record_pattern?action=history)). Available under [Creative Commons Attribution-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/). Changes may have been made.
