Objectiphy
  • Introduction
  • Quick Start
  • Basic Fetching
  • Basic Saving
  • Deleting
  • Mapping Providers
    • Attributes
    • Objectiphy Mapping
    • Doctrine Mapping
  • Defining Relationships
    • One to one
    • One to Many
    • Many to one
    • Many to Many
    • Scalar Joins
  • Query Builder
    • Running a Query
    • Select Queries
    • Update Queries
    • Insert Queries
    • Delete Queries
    • Criteria
      • Operators
      • Filtering by Child Objects
      • Filtering by Aggregates
    • Joins
  • Pagination and Sorting
  • Embedded Value Objects
  • Serialization Groups
  • Late Binding and Lazy Loading
  • Streaming Results
  • Custom Repositories
  • Optimisation
  • Configuration Options
  • Mapping Overrides
  • Caching
  • Comparison with Doctrine
  • Code Generation etc.
  • Troubleshooting
  • Licence, Copyright, Credits
Powered by GitBook
On this page

Was this helpful?

Custom Repositories

Keep your custom queries for a particular entity in one place.

PreviousStreaming ResultsNextOptimisation

Last updated 3 years ago

Was this helpful?

A plain ObjectRepository class can be used for reading and writing objects of any type. For simple use cases, you can just use an instance of ObjectRepository directly; you don't need a custom repository class of your own. There are advantages to having a custom repository class though, especially if you write a lot of custom queries - ie. you can keep all your queries in the repository class, and just call methods on that custom repository, rather than littering your service classes with queries.

Some people like to have a custom repository class for every entity, which can result in hundreds of repository classes in a large application. Often, these classes are left completely empty, and just extend the base repository class - they are unnecessary, but are there 'just in case' you want to add methods later.

There is some rationale behind this - the class is ready for you to add your own methods without needing to change any dependency wiring, and you could use to create entities and repositories, so that there is no great development burden in doing so. However, it does introduce code bloat, and not everyone likes to rely on code generation. Also, Objectiphy does not have any code generation features, and Doctrine's code generation will not create Objectiphy repository classes, so you would have to create your own. You might therefore prefer to mainly use plain ObjectRepository instances, and only create custom repositories where necessary. Or create custom repositories for every entity - it is up to you.

To create a custom repository class, extend the ObjectRepository class, and add your own methods as required, for example:

<?php

namespace \MyProject\Repositories;

use Objectiphy\Objectiphy\Orm\ObjectRepository;
use Objectiphy\Ojbectiphy\Query\QB;

class ContactRepository extends ObjectRepository
{
    public function findSmithsInDept(int $departmentId)
    {
        $query = QB::create()
            ->where('surname', '=', 'Smith')
            ->and('department', '=', $departmentId);
        
        return $this->findBy($query);
    }
}

Forcing the use of a custom repository

Typically, all you need to do to use a custom repository is tell the repository factory the class name of your repository and let it create it for you. However, if you are intercepting calls to the repository and need to make sure that your custom repository is always used for a particular entity - even if the entity is being loaded as a child of a parent entity which does not use your repository, you can do one of two things:

Where a custom repository has been specified for an entity, Objectiphy will defer to that custom repository class every time it tries to load an entity of that type. However, if the entity is loaded via a join (due to an eager loaded one-to-one or many-to-one relationship), the parent entity's repository will still be used. If you want to ensure that your custom repository is used even for eager loaded one-to-one and many-to-one relationships, you can set the alwaysLateBind attribute to true. If you do this though, a separate database call has to be made using a new instance of the custom repository, so performance will suffer.

You still need to use the to create custom repositories - if you try to create them or autowire them without using the factory, you will have problems!

Use the repositoryClassName attribute of the to specify the fully qualified class name of the custom repository.

for the @Table annotation to specify a repository class name if it is not specified on the entity.

code generation
repository factory
Override the mapping
@Table annotation