Edit:
I've prepared a tar.gz which once uncompressed and after running ./bin/vendors install fails to load the fixtures through php scripts/createAll.php. In the tar.gz there are 2 bundles using 2 different connections everyone with its own database.
I think Symfony2 fails to manage them properly. If you take a look at scripts/createAll.php will see how symfony fails to load both fixtures, but if you remove a random fixture (it doesn't matter Var_.php or Foo_.php everything runs fine, which seems to me that symfony is failing to manage entities correctly.)
LINK: http://www.2shared.com/file/2u4GhFVX/SymfonyTestCasetar.html
i want to tell Symfony2 to use different entity managers for different Bundle
directories so my config.yml looks like:
orm:
auto_generate_proxy_classes: %kernel.debug%
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
myVendorURLCoreBundle: ~
myVendormyBundleBundle: ~
myVendormyBundleFooBundle:
prefix: "myVendor\myBundleFooBundle\Entity"
type: annotation
is_bundle: true
dir: "/Entity"
formacions:
connection: formacions
mappings:
myVendormyBundleFooBarBundle:
prefix: "myVendor\myBundleFooBarBundle\View"
type: annotation
is_bundle: false
dir: "%kernel.root_dir%/../src/myVendor/myBundleFooBarBundle/View"
The problem is when using relationships between the entities in the different directories i get the following error caused by vendor/doctrine/lib/Doctrine/ORM/Mapping/MappingException.php at line 142
Class FRJPC\SalleUrlFormacionsBundle\Entity\EspecialitatContingut is
not a valid entity or mapped super class
The probem is that sometimes "\" before the vendor name breaks the namespace. It's really strange.
Here is how i i link entities between each other:
namespace myVendor\myBundleFooBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity( repositoryClass="myVendor\myBundleFooBundle\Repository\ARepository" )
* #ORM\ChangeTrackingPolicy( "DEFERRED_EXPLICIT" )
* #ORM\Table( name="a" )
*/
class A
{
/**
* #ORM\Id
* #ORM\Column( type="integer", length="4" )
* #ORM\GeneratedValue( strategy="AUTO" )
*/
private $id;
/**
* #ORM\ManyToOne( targetEntity="\myVendor\myBundleFooBarBundle\Entity\B", inversedBy="a", cascade={"persist"} )
* #ORM\JoinColumn( name="FooBar", nullable=true, referencedColumnName="FooBar", onDelete="CASCADE" )
*/
private $fooBar;
}
Second entity:
namespace myVendor\myBundleFooBarBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity( repositoryClass="myVendor\myBundleFooBarBundle\Repository\ARepository" )
* #ORM\ChangeTrackingPolicy( "DEFERRED_EXPLICIT" )
* #ORM\Table( name="a" )
*/
class B
{
/**
* #ORM\Id
* #ORM\Column( type="integer", length="4" )
* #ORM\GeneratedValue( strategy="AUTO" )
*/
private $id;
/** #ORM\OneToMany( targetEntity="\myVendor\myBundleFooBundle\Entity\EspecialitatContingut", mappedBy="fooBar" ) */
private $a;
}
Does any one has a clue on how should i link each entity ?
PD: Both entities work like charm when they're in the same bundle and same directory.
All these Foos and Bars combined with an error message with a real name make it a bit difficult to follow and leaves open the possibility that posted code really doesn't match the actual code. The FooBarBundle/View seems to be an unlikely place to store entities.
In any event a given entity manager such as formacions needs to be able to see all the relevant entities including those involved in relations. It looks like you defined A in the foo bundle and B in the bar bundle and they both cross reference each other?
From your config, I don't see how the formacion em can see your A entity and likewise I don't see how the default em can see the B entity. The fully qualified class name in the relation is not enough to share the entity doctrine metadata. Hence the error messages.
I'd would actually be glad to be proven wrong about this. It's a bit frustrating not to be able to do these sorts of things.
Related
I have got logging working on my entity so that when I make a change to a product field with the #Gedmo\Versioned annotation a new version is created. However the only problem is that the username field remains NULL. There is an authenticated user as the update is performed in Sonata Admin backend.
<?php
namespace MyApp\CmsBundle\Entity\Log;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry;
use Gedmo\Loggable\Entity\Repository\LogEntryRepository;
/**
* #ORM\Entity(repositoryClass="Gedmo\Loggable\Entity\Repository\LogEntryRepository", readOnly=true)
* #ORM\Table(
* name="log_product",
* indexes={
* #ORM\Index(name="log_class_lookup_idx", columns={"object_class"}),
* #ORM\Index(name="log_date_lookup_idx", columns={"logged_at"}),
* #ORM\Index(name="log_user_lookup_idx", columns={"username"}),
* }
* )
*/
class ProductLog extends AbstractLogEntry
{
}
So it would appear the log_user_lookup_idx isn't working correctly, is there a particular bit of config I require for this?
It appears I was missing a bit of config, adding the following to the main app/config/config.yml file did the trick.
stof_doctrine_extensions:
default_locale: en
orm:
default:
loggable: true
I did originally have this in my bundles' services.yml config:
gedmo.listener.loggable:
class: Gedmo\Loggable\LoggableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ "#annotation_reader" ] ]
This managed to track the entity being modified but not the user, I have since removed this config and the logging remains to work with just the stof_doctrine_extensions config setting.
If you have both in your code base then everything will be logged twice I found.
I'm trying to extend the User Entity of the sonata user bundle, but it always fails (at least when I want to use ist with the sonata admin bundle). If I use the Application/Sonata/UserBundle/Entity/User Entity it works and I can edit it in the dashboard.
My Entity looks like this:
<?php
namespace MyNamespace\MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\EntityManager;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
In my config.yml I defined the following options:
fos_user:
db_driver: orm
firewall_name: main
user_class: MyNamespace\MyBundle\Entity\User
group:
group_class: Application\Sonata\UserBundle\Entity\Group
group_manager: sonata.user.orm.group_manager
service:
user_manager: sonata.user.orm.user_manager
And:
sonata_user:
security_acl: true
manager_type: orm
class:
user: MyNamespace\MyBundle\Entity\User
The login is working correctly, but then I get the error message
"An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "admin_sonata_user_user_create" as such route does not exist.") in SonataAdminBundle:Block:block_admin_list.html.twig at line 39."
My routing.yml looks like this:
admin:
resource: '#SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
prefix: /
_sonata_admin:
host: www.mydomain.com
resource: .
type: sonata_admin
prefix: /
schemes: [https]
Even if I follow this tutorial (Extending Sonata User Bundle and adding new fields) step by step I get the same error.
Application/Sonata/UserBundle/Entity/User is extended Sonata/UserBundle/Entity/User so why not just to make changes there instead of another class?
It's already extended bundle so you can make all the changes there. I put my additional fields there.
My file Application/Sonata/UserBundle/Entity/User.php is like:
namespace Application\Sonata\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
/**
* User
* #ORM\Entity
* #ORM\Table(name="fos_user_user")
*/
class User extends BaseUser
{
/**
* #var integer
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*/
private $company;
If your really want to use another class you need to take care about routing.
Check \vendor\sonata-project\user-bundle\Resources\config\admin_orm.xml - it's the place where original class is added as a service.
You can see there %sonata.user.admin.user.entity% parameter - you could change this in config if you want to change to another class. I think it's better than changing fos_user.user_class.
You can also move the whole file to your Application/Sonata/UserBudle but then you need to load it inside DependencyInjection/ApplicationSonataUserExtension.php
Btw, this is really tricky in Sonata which user bundles as Paweł wrote and takes a lot of debugging to make it work
I am upgrading an application from Symfony 2.0 to Symfony 2.1, I followed this upgrade file and all works fine except that after a cache:clear I get an error when using some repositories. Here is the error:
[Semantical Error] The annotation "#ORM\Table" in class
edasiclinic\AlertesBundle\Repository\AlertesRepository was never imported. Did you maybe
forget to add a "use" statement for this annotation?
This is one example, I get this error with other repositories. I don't understand why I have to import #ORM\Table inside a repository file if I don't use annotation there.
Also if I wait for ~10 seconds and then refresh the browser, it works...
EDIT
This is the Entity:
<?php
namespace edasiclinic\DatabaseBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* edasiclinic\DatabaseBundle\Entity\Alertes
*
* #ORM\Table(name="alertes")
* #ORM\Entity(repositoryClass="edasiclinic\AlertesBundle\Repository\AlertesRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Alertes
{
/**
* #var integer $id
*
* #ORM\Id
* #ORM\Column(name="idAlerta", type="integer")
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
...
}
And this the repository class:
<?php
namespace edasiclinic\AlertesBundle\Repository;
use Doctrine\ORM\EntityRepository;
use edasiclinic\DasiBundle\Funcions\AES;
class AlertesRepository extends EntityRepository
{
public function countUnread($user, $idioma, $fus)
{
// ...
}
}
Thanks
I had this very same problem today. the solution, after some googling, is apparently to include a comment block before the Repository class definition.
in your case:
/**
* AlertesRepository
*/
class AlertesRepository extends EntityRepository
{
...
}
without that comment block, you will receive the nonsensical error about "#ORM\Table". yet another Symfony/Doctrine oddity >_>
It was a PHP bug in versions prior to 5.3.8. From the symfony system requirements:
$this->addRecommendation(
version_compare($installedPhpVersion, '5.3.8', '>='),
'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156',
'Install PHP 5.3.8 or newer if your project uses annotations.'
);
See PHP bug #55156 for more details and possible workaround if you're unable to upgrade to a PHP version >= 5.3.8.
Looks like you forgot to add the use statement.
<?php
namespace Acme\MyBundle\Entity;
// Remember to include this use statement
use Doctrine\ORM\Mapping as ORM;
/**
* My Entity
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Acme\MyBundle\Entity\MyEntityRepository")
*/
class MyEntity
{
}
For me it only hapens with certain versions of PHP and the solution was to put the Repository class in a folder above the folder of entity class
I have a problem with overriding an entity.
I need the field emailCanonical to be not be unique.
Here is what I've done:
In my UserBundle\Resources\config\doctrine\User.orm.xml I've added the following attribute-overrides configuration, according to the Doctrine2 documentation
<attribute-overrides>
<attribute-override name="emailCanonical">
<field column="email_canonical" unique="false" name="emailCanonical" />
</attribute-override>
</attribute-overrides>
Then I ran the following console commands
$ php app/console doctrine:migrations:diff
$ php app/console doctrine:migrations:migrate
Everything worked fine. emailCanonical was made non unique.
But now, when I need to generate an entity in other bundles of project, I have a strange error:
$ php app/console doctrine:generate:entities SkyModelsBundle:Category
Generating entity "Sky\Bundle\ModelsBundle\Entity\Category"
[Doctrine\ORM\Mapping\MappingException]
Invalid field override named 'emailCanonical' for class 'Sky\Bundle\UserBundle\Entity\User'.
doctrine:generate:entities [--path="..."] [--no-backup] name
However, if I remove the override settings from xml mapping, everything works fine.
You override using PHP annotations like so (This is supported starting from doctrine version 2.3 and above, please note that in the documentation it mentions that you cannot override types , however I was able to do so using the latest version of doctrine , at the time of writing it is 2.4.4):
<?php
namespace Namespace\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use FOS\UserBundle\Model\User as BaseUser;
/**
* User
* #ORM\Entity
* #ORM\AttributeOverrides({
* #ORM\AttributeOverride(name="id",
* column=#ORM\Column(
* name = "guest_id",
* type = "integer",
* length = 140
* )
* )
* })
*/
class myUser extends BaseUser
{
/**
* #ORM\Id()
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
This is specified in the documentation at: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#overrides
I believe the name attribute of the field tag is not required, since it is already specified for the attribute-override tag
Try this
<attribute-overrides>
<attribute-override name="emailCanonical">
<field column="email_canonical" unique="false" />
</attribute-override>
</attribute-overrides>
Quote from official documentation, so may be its the only way.
If you need to change the mapping (for instance to adapt the field
names to a legacy database), the only solution is to write the whole
mapping again without inheriting the mapping from the mapped
superclass.
It seems that FOSUserBundle entities aren't imported correctly into your project.
Make sure FOSUserBundle is present in "mappings" section ("doctrine" branch) of your config.yml
doctrine:
orm:
entity_managers:
default:
connection: default
mappings:
AcmeDemoBundle: ~
FOSUserBundle: ~
Got the same bug just now, and I solved it. Doctrine throws this Mappingexception in ClassMetadataInfo when it cannot find the related property (attribute or relation) in its mapping.
So, in order to override "emailCanonical" attribute, you need to use "attribute-overrides" and "attribute-override" (as you did), and redefine php class property in your entity :
<?php
...
class YourUser extends BaseUser
{
...
/**
* Email canonical
*
* #var string
*
* #ORM\Column(name="email_canonical", type="string", length=255, unique=false)
*/
protected $emailCanonical;
#EDIT : using this solution causes me another bug.
It solved the one about "Invalid field override named…", but I got another one with "Duplicate definition of column…" when trying to validate schema with php app/console doctrine:schema:validate command.
Any idea ?
Your class that extends BaseUser should be like this:
<?php
namespace Namespace\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* User
* #ORM\Entity
* #ORM\Table(name="user")
* #UniqueEntity(fields="email", message="your costum error message")
*
*/
class myUser extends BaseUser
{
/**
* #ORM\Id()
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
?>
I know this is an old post, but i found a solution, at least it worked for me, maybe it would be helpful for someone else.
Well, i had the same issue and i'm using a custom manager for the fos_user, in the declaration file config.yml under doctrine entity_manager custom manager i declared the mapping to FOS_userBundle, BUT what was missing is to tell FOS_user that we use a diffrent manager and that's by adding :
fos_user:
---- db_driver: orm
---- model_manager_name: MyCustom_Manager
I'm getting this error when I try to clear the cache (for example):
[Doctrine\ORM\Mapping \MappingException] Class
Aib\PlatformBundle\Entity\User is not a valid entity or mapped super
class.
This is User.php:
<?php
// src/Aib/PlatformBundle/Entity/User.php
namespace Aib\PlatformBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
// your own logic
}
}
And this is the place where User.php is stored:
javier#javier:~/programacion/aib/src/Aib/PlatformBundle/Entity$ ls
User.php UserRepository.php
This is the AppKernel.php:
public function registerBundles()
{
$bundles = array(
...
new Aib\PlatformBundle\AibPlatformBundle(),
...
);
sf 2.0.4
In my case I was missing * #ORM\Entity in my class definition.
/**
* #ORM\Entity
* #ORM\Table(name="listtype")
*/
class ListType
{
...
}
I had the exact same experience with my implementation of the FOS UserBundle and found I was able to resolve the issue by removing the MyBundle\Resources\config\doctrine folder.
I dont fully understand the cause (newbie) but think the issue is a result of having database content built in bother directions, ie from doctrine entities and by reverse engineering some tables.
I had the same problem and it turned out to be the app/config/config.yml
It needed the defintion of the default bundle as below NameBundle, then it worked fine
orm:
auto_generate_proxy_classes: %kernel.debug%
default_entity_manager: default
entity_managers:
default:
mappings:
NameBundle: ~
In my case the problem was solved by changing my servers cache from eAccelerator to APC.
Apparently eAccelerator strips all the comments from files which breaks your annotations.
I had the same error, but this was because I wasn't including the Sonata Application:
try this:
add a line to your AppKernel.php
$bundles = array(
...
new Application\Sonata\UserBundle\ApplicationSonataUserBundle(),
...
If you inherited from mapped class, you can add #ORM\SuperMappedClass in entity's annotation.
You can read most information in this article.