I am trying to get the Stof\DoctrineExtensionsBundle to run to be able to use DoctrineExtensions easily. However, the PHP interpreter tells me:
No identifier/primary key specified for Entity 'Stof\DoctrineExtensionsBundle\Entity\Translation'. Every Entity must have an identifier/primary key.
Does anyone know how to circumvent this problem? I guess it is possible somewhere in the annotations of Doctrine2, but I do not understand it that much and there already is an "orm:index" value (renaming it by "orm:Id", which seems to be the required value, does not work).
That’s the code of Translation entity class shipped with DoctrineExtensions:
/**
* Stof\DoctrineExtensionsBundle\Entity\Translation
*
* #orm:Entity(repositoryClass="Gedmo\Translatable\Entity\Repository\TranslationRepository")
* #orm:Table(
* name="ext_translations",
* indexes={#orm:index(name="translations_lookup_idx", columns={
* "locale", "object_class", "foreign_key"
* })},
* uniqueConstraints={#orm:UniqueConstraint(name="lookup_unique_idx", columns={
* "locale", "object_class", "foreign_key", "field"
* })}
* )
*/
class Translation extends AbstractTranslation
{
}
By the way, that’s the git repository if this helps anything. But I was not able to find this point within the documentation: https://github.com/stof/DoctrineExtensionsBundle
You can try to disable the stofdoctrineextensions in your app/config/config.yml before generate your entities getters/setters like this:
mappings:
StofDoctrineExtensionsBundle: false
Looks like the entities generator doesn't support external mapping yet.
Related
I have a problem querying my database via Symfony Repository.
If I don't specify a repository
/**
* ProductsText
*
* #ORM\Table(name="products_text")
* #ORM\Entity
*/
i can select one of my databases by using Doctrine like this:
->getRepository(ProductsText::class, "db1").
But if i declare the repository:
/**
* ProductsText
*
* #ORM\Table(name="products_text")
* #ORM\Entity(repositoryClass="App\Repository\Product\ProductsTextRepository")
*/
It only selects the database from which I pulled the entity from.
I can't use two different entities because the user selects the "database" when logging in. Unfortunately, I can't merge the two databases yet either, as they are not multi-tenant.
My guess is that I can solve the problem by keeping the registry from the repository in general. My previous attempts unfortunately ended up with the front end no longer loading.
Works, but only for one database:
class ProductsTextRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, ProductsText::class);
}
Did not works:
class TbProductsTextRepository
{
/**
* #var EntityRepository
*/
private $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(TbProductsText::class);
}
Unfortunately, I don't understand the mechanics of how the repositorys are regestrated.
I use:
Symfony 5.2
Doctrine 2.2
Doctrine ORM 2.8
Doctrine Migrations Bundle 3.0
I solved the problem by not "registering" the repository.
By using EntityRepository and without a construct, I can use the repository for both databases.
use Doctrine\ORM\EntityRepository;
class TbProductsTextRepository extends EntityRepository
{
I just fixed some things in my code. I'm now trying to validate my schema
php bin/console doctrine:schema:validate
Doctrine tells me my mapping is correct but my database schema is not. So I'm doing a
schema:update --dump-sql
which results in the same ALTER again and again, that I already performed many times.
Here is the ALTER :
ALTER TABLE migration_versions CHANGE version version VARCHAR(14) NOT NULL;
I did it (with --force), the entity is reflecting the change already :
**
* MigrationVersions
*
* #ORM\Table(name="migration_versions")
* #ORM\Entity
*/
class MigrationVersions
{
/**
* #var string
*
* #ORM\Column(name="version", type="string", length=14, nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $version;
I am correct right ? its varchar, lenght 14...
And so is it in my database
I don't think Im making a mistake here but I may be missing something.
Have you already verified that the server_version in the doctrine config file is correct? (config/packages/doctrine.yaml in symfony5)
It happened to me that I was using MariaDB (version 10.4.11-MariaDB - Source distribution) and in the file doctrine.yaml the server_version parameter had the value 5.7.
After I corrected that, the error no longer occurred.
Also you can check this question
Sometimes, I just need to place the value with a config from the end user, just like the database prefix, uploaded File maxSize like below, and etc...
/**
* File
*
* #ORM\Table(name="{projectName}media_file")
* #ORM\Entity(repositoryClass="FileRepository")
* #ORM\HasLifecycleCallbacks()
*/
class File
{
/**
* #var File
*
* #Assert\File(maxSize="{configFromYML}")
*/
protected $file;
What can I do for it? thanks
As far as I know, this is not possible: the configuration parameters are only available in the container.
For the table prefix, maybe you can use the following solution:
How to setup table prefix in symfony2
For the validation, I think the only way to do this is to create a custom validation constraint and to configure it as a service: http://symfony.com/doc/master/validation/custom_constraint.html#constraint-validators-with-dependencies
Hope this will help!
Summary
My problem is connected with the fact that the entity field marked with #Gedmo\UploadableFilePath annotation is ignored by Symfony3. I am using the Uploadable behavior extension for Doctrine2.
CODE
In my entity I have:
/**
* #ORM\Column
* #Gedmo\UploadableFileName
*/
private $name;
/*
* #ORM\Column
* #Gedmo\UploadableFilePath
*/
private $path;
SYMPTOMS
At first, I have noticed though that the path column is not generated in MySQL.
Then I found out that whenever I delete name field I get the following error:
[Gedmo\Exception\InvalidMappingException] Class
"AppBundle\Entity\plik" must have an UploadableFilePath or Uploadable
FileName field.
Documentation
In doctrine-uploadable documentation I see that:
#Gedmo\Mapping\Annotation\UploadableFilePath: This annotation is used
to set which field will receive the path to the file. The field MUST
be of type "string". Either this one or UploadableFileName annotation
is REQUIRED to be set.
so it seems that I should be able to set $path field only.
Help request
Please advice why is UploadableFilePath field not being generated and why can't I delete the $name field?
It seems that I have made a simple typo. There was lack of one * in the comment line.
/**
* #ORM\Column
* #Gedmo\UploadableFilePath
*/
private $path;
It seems that symfony ignores annotations in such a case.
I have an Entity called Game with a related Repository called GameRepository:
/**
* #ORM\Entity(repositoryClass="...\GameRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Game {
/**
* #ORM\prePersist
*/
public function setSlugValue() {
$this->slug = $repo->createUniqueSlugForGame();
}
}
In the prePersist method, I need to ensure that the Game's slug field is unique, which requires a database query. To do the query, I need access to the EntityManager. I can get the EntityManager from inside GameRepository. So: how do I get the GameRespository from a Game?
You actually can get the repository in your entity and only during a lifecycle callback. You are very close to it, all you have to do is to receive the LifecycleEventArgs parameter.
Also see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html
use Doctrine\ORM\Event\LifecycleEventArgs;
/**
* #ORM\Entity(repositoryClass="...\GameRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Game {
/**
* #ORM\prePersist
*/
public function setSlugValue( LifecycleEventArgs $event ) {
$entityManager = $event->getEntityManager();
$repository = $entityManager->getRepository( get_class($this) );
$this->slug = $repository->createUniqueSlugForGame();
}
}
PS. I know this is an old question, but I answered it to help any future googlers.
You don't. Entities in Doctrine 2 are supposed to not know of the entity manager or the repository.
A typical solution to the case you present would be to add a method to the repository (or a service class) which is used to create (or called to store) new instances, and also produces a unique slug value.
you can inject the doctrine entity manager in your entity
(using JMSDiExtraBundle)
and have the repository like this:
/**
* #InjectParams({
* "em" = #Inject("doctrine.orm.entity_manager")
* })
*/
public function setInitialStatus(\Doctrine\ORM\EntityManager $em) {
$obj = $em->getRepository('AcmeSampleBundle:User')->functionInRepository();
//...
}
see this : http://jmsyst.com/bundles/JMSDiExtraBundle/1.1/annotations
In order to keep the logic encapsulated without having to change the way you save the entity, instead of the simple prePersist lifecycle event you will need to look at using the more powerful Doctrine events which can get access to more than just the entity itself.
You should probably look at the DoctrineSluggableBundle or StofDoctrineExtensionsBundle bundles which might do just what you need.