PHPackages                             oasis/doctrine-addon - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. oasis/doctrine-addon

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

oasis/doctrine-addon
====================

Doctrine add-ons

v3.1.2(1mo ago)09.9k1MITHTMLPHP ^8.4

Since May 11Pushed 1mo ago3 watchersCompare

[ Source](https://github.com/oasmobile/php-doctrine-addon)[ Packagist](https://packagist.org/packages/oasis/doctrine-addon)[ RSS](/packages/oasis-doctrine-addon/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependencies (8)Versions (15)Used By (1)

oasis/doctrine-addon
====================

[](#oasisdoctrine-addon)

[Doctrine ORM](http://doctrine-project.org/projects/orm.html) 扩展组件，提供：

- **AutoIdTrait** — 简化自增主键声明
- **CascadeRemoveTrait** — 解决使用数据库 `ON DELETE CASCADE` 时，EntityManager identity map 和 Second Level Cache 中残留脏数据的问题

Installation
------------

[](#installation)

```
composer require oasis/doctrine-addon
```

AutoIdTrait
-----------

[](#autoidtrait)

`use AutoIdTrait` 即可获得自增整数主键 `$id` 和 `getId()` 方法：

```
/**
 * @ORM\Entity()
 */
class User
{
    use AutoIdTrait;
}
```

The Cascade Removal Problem
---------------------------

[](#the-cascade-removal-problem)

当 ORM 启用 Second Level Cache 并使用数据库 `ON DELETE CASCADE` 约束时，删除父 entity 后：

1. **Identity map 脏数据** — `$em->find()` 仍然返回已被数据库删除的子 entity
2. **二级缓存脏数据** — 缓存中仍持有已删除 entity 的数据
3. **关联集合不一致** — 持有被删除 entity 引用的其他 entity，其集合未被刷新

> 例如：Team entity 持有 User 集合。删除一个 User 后，访问 Team 的 members 集合仍会拿到已删除的 User 引用，导致异常。

Doctrine 原生方案各有缺陷：

- **手动失效**：复杂，关联链越深越容易遗漏
- **`cascade={"remove"}`**：ORM 逐条发 DELETE 语句，关联复杂时性能极差

CascadeRemoveTrait Solution
---------------------------

[](#cascaderemovetrait-solution)

通过 Doctrine 生命周期回调，在 `PreRemove` 阶段递归收集关联实体，在 `PostRemove` 阶段统一 detach + evict + refresh。实际删除由数据库 `ON DELETE CASCADE` 完成。

### Prerequisites

[](#prerequisites)

- Entity 必须启用 Doctrine Second Level Cache（`@ORM\Cache` 注解）
- 强关联实体的数据库外键必须设置 `ON DELETE CASCADE`

### Usage

[](#usage)

```
/**
 * @ORM\Entity()
 * @ORM\Table(name="categories")
 * @ORM\Cache(usage="NONSTRICT_READ_WRITE")
 * @ORM\HasLifecycleCallbacks()
 */
class Category implements CascadeRemovableInterface
{
    use CascadeRemoveTrait;
    use AutoIdTrait;

    /** @ORM\OneToMany(targetEntity="Article", mappedBy="category") */
    protected $articles;

    public function getCascadeRemoveableEntities()
    {
        // 强关联：删除 Category 时，其下的 Article 也应删除
        return $this->articles->toArray();
    }

    public function getDirtyEntitiesOnInvalidation()
    {
        // 弱关联：无（Category 删除不需要刷新其他 entity 的缓存）
        return [];
    }
}
```

### Key Concepts

[](#key-concepts)

概念说明`getCascadeRemoveableEntities()` 返回**强关联实体**当前实体删除时也应删除的实体Category → Article**弱关联实体**持有当前实体引用、需刷新缓存的实体Article → Tag（通过 `getDirtyEntitiesOnInvalidation()`）### What the Trait Does

[](#what-the-trait-does)

阶段强关联实体弱关联实体PreRemove递归收集收集（排除已在强关联列表中的）PostRemovedetach from EM + evict from L2 cacheevict from L2 cache + refresh from DB完整的 CMS 示例（Category / Article / Tag）见 `ut/Entity/` 目录。

Development
-----------

[](#development)

```
# 安装依赖
composer install

# 运行测试（零外部依赖，使用 SQLite in-memory）
vendor/bin/phpunit

# 覆盖率报告（需要 pcov 扩展）
vendor/bin/phpunit --coverage-text --whitelist=src/
```

详见 `docs/manual/development.md`。

License
-------

[](#license)

MIT

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance90

Actively maintained with recent releases

Popularity22

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity88

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~331 days

Recently: every ~1 days

Total

12

Last Release

52d ago

Major Versions

v1.1.0 → v2.0.02016-06-22

v2.1.0 → v3.0.02026-04-29

### Community

Maintainers

![](https://www.gravatar.com/avatar/0d3f8d2ee766764d8a377c91eea457b7089bbf7e90b2cec151e8095ed1b129bc?d=identicon)[no7mks](/maintainers/no7mks)

---

Top Contributors

[![no7mks](https://avatars.githubusercontent.com/u/1235585?v=4)](https://github.com/no7mks "no7mks (49 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/oasis-doctrine-addon/health.svg)

```
[![Health](https://phpackages.com/badges/oasis-doctrine-addon/health.svg)](https://phpackages.com/packages/oasis-doctrine-addon)
```

###  Alternatives

[rcsofttech/audit-trail-bundle

Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.

1155.2k](/packages/rcsofttech-audit-trail-bundle)[codefog/contao-haste

haste extension for Contao Open Source CMS

41668.4k162](/packages/codefog-contao-haste)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
