Closed truckee closed 3 years ago
I'm afraid I can't help here because I don't understand why this happens. Please, try setting any of the config options related to pagination (see https://symfony.com/doc/master/bundles/EasyAdminBundle/crud.html#search-and-pagination-options).
Options tried: ->setPaginatorUseOutputWalkers(true)
and ->setPaginatorFetchJoinCollection(true)
Unfortunately, trying either or both of the paginations options in either the Representative or Nonprofit entity did not make a difference. In all cases only one of three possible entities was displayed; the same entity was displayed in each trial.
Edit: Created a fresh Symphony 5.1 full project & added only my entities & EA3. Copied the RepresentativeCrudController
from the original project into the fresh installation. The same behavior obtains, thus eliminating nearly all of the original project's code as a source of error.
Hi ! how are you? Can you help me. I have the same issue.
@belkoweb It would be useful if you could edit your post to show code - entities & controllers - producing the same issue.
I'm facing the exact same problem. Using xdebug leads to the problem that the method getPrimaryKeyValue
returns always null
. Therefore every time the same array key is overwritten with the latest entity.
EntityFactory.php
public function createCollection(EntityDto $entityDto, ?iterable $entityInstances): EntityCollection
{
$entityDtos = [];
foreach ($entityInstances as $entityInstance) {
$newEntityDto = $entityDto->newWithInstance($entityInstance);
$newEntityId = $newEntityDto->getPrimaryKeyValueAsString();
if (!$this->authorizationChecker->isGranted(Permission::EA_ACCESS_ENTITY, $newEntityDto)) {
$newEntityDto->markAsInaccessible();
}
$entityDtos[$newEntityId] = $newEntityDto;
}
return EntityCollection::new($entityDtos);
}
EntityDto.php -> always throws the exception Property id does not exist
public function getPrimaryKeyValue()
{
if (null === $this->instance) {
return null;
}
if (null !== $this->primaryKeyValue) {
return $this->primaryKeyValue;
}
try {
$r = ClassUtils::newReflectionObject($this->instance);
$primaryKeyProperty = $r->getProperty($this->primaryKeyName);
$primaryKeyProperty->setAccessible(true);
$primaryKeyValue = $primaryKeyProperty->getValue($this->instance);
} catch (\Exception $e) {
$primaryKeyValue = null;
}
return $this->primaryKeyValue = $primaryKeyValue;
}
I assume that the primary key property is private in your abstract user? Making it protected solved the issue for me.
@4lxndr Absolutely correct. Solves the problem so I'm closing the issue.
@4lxndr thanks for the details. However, why does it matter that your primary key is private? We use PHP reflection and force the primary key to be accessible. (That's why I'm reopening this issue) I'm missing something here 🤔 Also, could we do something in our code to help people debug this problem? Thanks!
It appears the failure occurs at line 84 in EntityDto
.
try {
$r = ClassUtils::newReflectionObject($this->instance);
$primaryKeyProperty = $r->getProperty($this->primaryKeyName); // line 84
$primaryKeyProperty->setAccessible(true);
$primaryKeyValue = $primaryKeyProperty->getValue($this->instance);
} catch (\Exception $e) {
$primaryKeyValue = null;
}
Edit: removed incorrect analysis. What is true is that when the parent User entity property id is protected
not private
, line 84 does not throw the Exception. The difference is that $this->instance
does not contain the property id
when it is private
.
protected $id;
instance:
private $id;
instance:
Thanks for the additional details.
This is really strange. I'm trying to reproduce this ... so I made my $id
property private in the entity and removed the getId()
method. The PHP reflection code worked as expected and it could extract the right property value:
Here's the equivalent in my app:
To expand on the issue: Representative is one of four entities defined in the User entity:
/**
* @ORM\Table(name="usertable")
* @ORM\Entity
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap({"rep" = "Representative", "volunteer" = "Volunteer", "admin" = "Admin"})
*/
abstract class User implements UserInterface
Each of those entities presents the identical problem when $id
is private. Any suggestion on how to determine if this is relevant?
Edit: I'm wondering if we've lost site of the original issue. When the id is private, one and only one entity is rendered, which is not consistent with the id not appearing in any of the Reflection classes. That single entity's id is available with a template including {{ dump(entity.instance.id) }}
.
Edit 2: While using xdebug trying to find out where the divergence happens between private & public id I stumbled on an exception. Changing private to protected resulted in
You cannot refresh a user from the EntityUserProvider that does not contain an identifier. The user object has to be serialized with its own identifier mapped by Doctrine
This does not occur when changing protected to private. But it is further evidence that the user entity (in this case admin
, one of the three user types) does not contain an identifier.
Edit 3:
I have identified a difference that may be significant. At AbstractCrudController:119 there is $entities = $this->get(EntityFactory::class)->createCollection($context->getEntity(), $paginator->getResults());
I serialized each of the parameters of createCollection()
and output them to text files. I then ran Windows fc
to compare the files between protected and private runs. The $paginator->getResults()
files were significantly different. Those files are attached. Interpreting the results are not in my skill set.
Edit 4: A close examination of these two files shows that the id of the Representative appears in a different sequence depending on whether the id is private or protected. For example:
protected:
N;s:36:" App\Entity\Representative completed";N;s:5:" * id";i:9;s:22:" App\Entity\User roles";a:1:{i:0;s:8:"ROLE_REP";}
private:
N;s:36:" App\Entity\Representative completed";N;s:19:" App\Entity\User id";i:9;s:22:" App\Entity\User roles";a:1:{i:0;s:8:"ROLE_REP";}
With protected $id;
the id appears to be associated with the Representative entity while with private $id;
it appears with the User entity. Why this is true I must leave for others to determine.
With apologies for my ignorance. The differences between private & public id properties are expected results from Doctrine. This I learned in a test outside of EA3. The question remains, though, is why there are differences in the display of users (which I believe comes from EA3).
Hi, I have the exact same problem here.
I got one entity Organization and 2 sub entities ClientOrganization and ResellerOrganization.
abstract class Organization
{
/**
* @var int
* @Expose
*/
private $id;
class ClientOrganization extends Organization {
/**
* @var integer
* @Expose
*/
private $id;
With the private $id
, the ClientOrganization list show only 1 line and a correct counter (3 in my case)
When I change to protected $id
, it's working, I can see all the values in the list.
My setup :
symfony/framework-bundle v5.1.8
easycorp/easyadmin-bundle v3.1.6
doctrine/common 3.0.2
I hope this will help you.
[With apologies for the duplicate of a post at SO] Describe the bug A Representative entity, mapped via joined inheritance to the User entity, in list view shows a count of 3 but displays only one. Representative is also in a ManyToOne relationship to the Nonprofit entity.
To Reproduce Unfortunately, I don't think this can be easily reproduced. It most likely requires a similar setup and data set. The issue does not appear in EA2, only in EA3.
Additional context Attached are listings copied from Symfony profiler of database queries from both EA2 & EA3. The significant difference is that EA2 queries all 3 nonprofits whereas EA3 queries only 1. There are no code differences between EA2 & EA3 for any entities.
Edit: Summary of db query sequence (staff is table name for Representative):
EA2-rep_list_view.txt EA3-rep_list_view.txt
Snippets from the relevant entities and the Representative CRUD controller. Representative entity (snippet):
User entity (snippet):
Nonprofit entity (snippet):
Representative CRUD Controller: