No identifier/primary key specified for Entity "App\Entity\RefreshToken"
edebertJurisoft opened this issue · 11 comments
Hello,
I have a mistake about property in id in RefreshToken :
No identifier/primary key specified for Entity "App\Entity\RefreshToken" sub class of "Gesdinet\JWTRefreshTokenBundle\Entity\RefreshToken". Every Entity must have an identifier/primary key.
This mistake is not there all time.
I try overload id in my Entity RefreshToken. Do you have a solution ?
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gesdinet\JWTRefreshTokenBundle\Entity\RefreshToken as BaseRefreshToken;
/**
* @ORM\Entity
* @ORM\Table("refresh_tokens")
*/
class RefreshToken extends BaseRefreshToken
{
protected $id;
public function getId()
{
return $this->id;
}
}
Configuration
Php version : 8.0.22
Symfony : 5.4
jwt-refresh-token-bundle : 1.1.1
lexik/jwt-authentication-bundle: 2.16.0
I don't use attributes php8.
Got the same issue here.
It happens when the cache is clearing with the following command:
php bin/console cache:clear
I also tried to override the id attribute and give him annotations to define it as a primary key
#[ ORM\Id, ORM\GeneratedValue, ORM\Column(type:"integer") ] protected $id;
But then I get the following issue:
Duplicate definition of column 'id' on entity 'App\Entity\RefreshToken' in a field or discriminator column mapping.
I guess it means that somehow, somewhere, the id attribute is defined as the primary key of the entity, but the doctrine mapping doesn't get it.
This probably means that we need to define it with the other attributes elsewhere, in the doctrine yaml ?
Configuration :
Php version: 8.1.5
Symfony: 6.1
gesdinet/jwt-refresh-token-bundle: ^v1.1.1
lexik/jwt-authentication-bundle: 2.8
Ok, I've found a solution, I believe it's temporary but it works, I create a custom entity extended on AbstractRefreshToken with all attributes clearly described:
namespace App\Entity;
use App\Repository\RefreshTokenRepository;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Gesdinet\JWTRefreshTokenBundle\Model\AbstractRefreshToken;
#[
ORM\Entity(repositoryClass: RefreshTokenRepository::class),
ORM\Table(name: 'jwt_refresh_tokens')
]
class JwtRefreshToken extends AbstractRefreshToken
{
#[
ORM\Id,
ORM\GeneratedValue,
ORM\Column(type:"integer")
]
protected $id;
#[
ORM\Column(type: "string", length: 128, nullable: true)
]
protected $refreshToken;
#[
ORM\Column(type:"string", length: 255, nullable: true)
]
protected $username;
#[
ORM\Column(type:"datetime", nullable: true)
]
protected $valid;
}
I also binded the entity with a repository that implements the RefreshTokenRepositoryInterface and add to it the needed methods.
And to change in the gesdinet_jwt_refresh_token.yml:
gesdinet_jwt_refresh_token:
refresh_token_class: App\Entity\JwtRefreshToken
the same issue here!
Could someone help me somehow here :/
it's my exception
{
"type": "https://tools.ietf.org/html/rfc2616#section-10",
"title": "An error occurred",
"status": 500,
"detail": "Attempted to call an undefined method named \"getId\" of class \"Symfony\\Component\\Security\\Core\\User\\User\".",
"class": "Symfony\\Component\\ErrorHandler\\Error\\UndefinedMethodError",
"trace": [
{
"namespace": "",
"short_class": "",
"class": "",
"type": "",
"function": "",
"file": "/usr/src/app/src/EventListener/JWTCreatedListener.php",
"line": 13,
"args": []
},
{
"namespace": "App\\EventListener",
"short_class": "JWTCreatedListener",
"class": "App\\EventListener\\JWTCreatedListener",
"type": "->",
"function": "onJWTCreated",
"file": "/usr/src/app/vendor/symfony/event-dispatcher/Debug/WrappedListener.php",
"line": 126,
"args": [
[
"object",
"Lexik\\Bundle\\JWTAuthenticationBundle\\Event\\JWTCreatedEvent"
],
[
"string",
"lexik_jwt_authentication.on_jwt_created"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher"
]
]
},
{
"namespace": "Symfony\\Component\\EventDispatcher\\Debug",
"short_class": "WrappedListener",
"class": "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener",
"type": "->",
"function": "__invoke",
"file": "/usr/src/app/vendor/symfony/event-dispatcher/EventDispatcher.php",
"line": 251,
"args": [
[
"object",
"Lexik\\Bundle\\JWTAuthenticationBundle\\Event\\JWTCreatedEvent"
],
[
"string",
"lexik_jwt_authentication.on_jwt_created"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher"
]
]
},
{
"namespace": "Symfony\\Component\\EventDispatcher",
"short_class": "EventDispatcher",
"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
"type": "->",
"function": "callListeners",
"file": "/usr/src/app/vendor/symfony/event-dispatcher/EventDispatcher.php",
"line": 73,
"args": [
[
"array",
[
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
]
]
],
[
"string",
"lexik_jwt_authentication.on_jwt_created"
],
[
"object",
"Lexik\\Bundle\\JWTAuthenticationBundle\\Event\\JWTCreatedEvent"
]
]
},
{
"namespace": "Symfony\\Component\\EventDispatcher",
"short_class": "EventDispatcher",
"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
"type": "->",
"function": "dispatch",
"file": "/usr/src/app/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php",
"line": 168,
"args": [
[
"object",
"Lexik\\Bundle\\JWTAuthenticationBundle\\Event\\JWTCreatedEvent"
],
[
"string",
"lexik_jwt_authentication.on_jwt_created"
]
]
},
{
"namespace": "Symfony\\Component\\EventDispatcher\\Debug",
"short_class": "TraceableEventDispatcher",
"class": "Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher",
"type": "->",
"function": "dispatch",
"file": "/usr/src/app/vendor/lexik/jwt-authentication-bundle/Services/JWTManager.php",
"line": 87,
"args": [
[
"object",
"Lexik\\Bundle\\JWTAuthenticationBundle\\Event\\JWTCreatedEvent"
],
[
"string",
"lexik_jwt_authentication.on_jwt_created"
]
]
},
{
"namespace": "Lexik\\Bundle\\JWTAuthenticationBundle\\Services",
"short_class": "JWTManager",
"class": "Lexik\\Bundle\\JWTAuthenticationBundle\\Services\\JWTManager",
"type": "->",
"function": "generateJwtStringAndDispatchEvents",
"file": "/usr/src/app/vendor/lexik/jwt-authentication-bundle/Services/JWTManager.php",
"line": 67,
"args": [
[
"object",
"Symfony\\Component\\Security\\Core\\User\\User"
],
[
"array",
{
"roles": [
"array",
[
[
"string",
"ROLE_USER"
]
]
],
"email": [
"string",
"elvis.jaskolski@gmail.com"
]
}
]
]
},
{
"namespace": "Lexik\\Bundle\\JWTAuthenticationBundle\\Services",
"short_class": "JWTManager",
"class": "Lexik\\Bundle\\JWTAuthenticationBundle\\Services\\JWTManager",
"type": "->",
"function": "create",
"file": "/usr/src/app/vendor/lexik/jwt-authentication-bundle/Security/Http/Authentication/AuthenticationSuccessHandler.php",
"line": 58,
"args": [
[
"object",
"Symfony\\Component\\Security\\Core\\User\\User"
]
]
},
{
"namespace": "Lexik\\Bundle\\JWTAuthenticationBundle\\Security\\Http\\Authentication",
"short_class": "AuthenticationSuccessHandler",
"class": "Lexik\\Bundle\\JWTAuthenticationBundle\\Security\\Http\\Authentication\\AuthenticationSuccessHandler",
"type": "->",
"function": "handleAuthenticationSuccess",
"file": "/usr/src/app/vendor/lexik/jwt-authentication-bundle/Security/Http/Authentication/AuthenticationSuccessHandler.php",
"line": 49,
"args": [
[
"object",
"Symfony\\Component\\Security\\Core\\User\\User"
]
]
},
{
"namespace": "Lexik\\Bundle\\JWTAuthenticationBundle\\Security\\Http\\Authentication",
"short_class": "AuthenticationSuccessHandler",
"class": "Lexik\\Bundle\\JWTAuthenticationBundle\\Security\\Http\\Authentication\\AuthenticationSuccessHandler",
"type": "->",
"function": "onAuthenticationSuccess",
"file": "/usr/src/app/vendor/gesdinet/jwt-refresh-token-bundle/Service/RefreshToken.php",
"line": 120,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
],
[
"object",
"Symfony\\Component\\Security\\Guard\\Token\\PostAuthenticationGuardToken"
]
]
},
{
"namespace": "Gesdinet\\JWTRefreshTokenBundle\\Service",
"short_class": "RefreshToken",
"class": "Gesdinet\\JWTRefreshTokenBundle\\Service\\RefreshToken",
"type": "->",
"function": "refresh",
"file": "/usr/src/app/vendor/symfony/http-kernel/HttpKernel.php",
"line": 169,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
]
]
},
{
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "HttpKernel",
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"type": "->",
"function": "handleRaw",
"file": "/usr/src/app/vendor/symfony/http-kernel/HttpKernel.php",
"line": 81,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
],
[
"integer",
1
]
]
},
{
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "HttpKernel",
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"type": "->",
"function": "handle",
"file": "/usr/src/app/vendor/symfony/http-kernel/Kernel.php",
"line": 201,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
],
[
"integer",
1
],
[
"boolean",
true
]
]
},
{
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "Kernel",
"class": "Symfony\\Component\\HttpKernel\\Kernel",
"type": "->",
"function": "handle",
"file": "/usr/src/app/public/index.php",
"line": 32,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
]
]
}
]
}
lexik/jwt-authentication-bundle v2.16.0 This bundle provides JWT authentication for your Symfony REST API
gesdinet/jwt-refresh-token-bundle v1.1.1 Implements a refresh token system over Json Web Tokens in Symfony
symfony/framework-bundle v4.4.47 Provides a tight integration between Symfony components and the Symfony full-stack framework
symfony/http-client v4.4.47 Provides powerful methods to fetch HTTP resources synchronously or asynchronously
symfony/http-client-contracts v2.5.2 Generic abstractions related to HTTP clients
symfony/http-foundation v4.4.48 Defines an object-oriented layer for the HTTP specification
symfony/http-kernel v4.4.48 Provides a structured process for converting a Request into a Response
Ok I solved it adding a new service provider
gesdinet_jwt_refresh_token:
user_identity_field: username
refresh_token_class: App\Entity\RefreshToken
user_provider: fos_user.user_provider.username_email
If you have doctrines auto_mapping
set to false
, you need to add the vendors mapping to your own:
<?php
declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('doctrine', [
'orm' => [
'auto_mapping' => false,
'mappings' => [
...
'VendorRefreshToken' => [
'type' => 'xml',
'dir' => '%kernel.project_dir%/vendor/gesdinet/jwt-refresh-token-bundle/Resources/config/doctrine',
'prefix' => 'Gesdinet\JWTRefreshTokenBundle\Entity',
],
],
],
]);
};
(maybe also when auto_mapping
is true
, I don't know, its false
in my project)
I just had a headache with this issue.
@darthf1 's solution is by far the cleanest I can think of.
Thank you, I was not sure how to configure a second mapping entry inside my main EntityManager. This works like a charm 👍
Here's the same but with yaml :
# [...]
mappings:
main:
# [...]
refresh_token:
type: xml
dir: '%kernel.project_dir%/vendor/gesdinet/jwt-refresh-token-bundle/Resources/config/doctrine'
prefix: 'Gesdinet\JWTRefreshTokenBundle\Entity'
Hi, i have same error with symfony 6.2 and gesdinet/jwt-refresh-token-bundle 1.1.3.
For fix this, i override abstract fields like this :
<?php
namespace App\Entity;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Gesdinet\JWTRefreshTokenBundle\Entity\RefreshTokenRepository;
use Gesdinet\JWTRefreshTokenBundle\Model\AbstractRefreshToken as BaseAbstractRefreshToken;
#[
ORM\Entity(
repositoryClass: RefreshTokenRepository::class,
),
ORM\Table('refresh_tokens')
]
class RefreshToken extends BaseAbstractRefreshToken
{
#[
ORM\Id,
ORM\Column(
name: 'id',
type: Types::INTEGER,
nullable: false,
),
ORM\GeneratedValue(strategy: 'AUTO'),
]
protected $id;
#[
ORM\Column(
name: 'refresh_token',
type: Types::STRING,
nullable: false,
)
]
protected $refreshToken;
#[
ORM\Column(
name: 'username',
type: Types::STRING,
nullable: false,
),
]
protected $username;
#[
ORM\Column(
name: 'valid',
type: Types::DATETIME_MUTABLE,
nullable: false,
)
]
protected $valid;
}
Seems to be a bit of a false positive somewhere tbh.
When you straight up delete the deprecated class locally and run tests it'll work fine and without deprecation
Hi, i have same error with symfony 6.2 and gesdinet/jwt-refresh-token-bundle 1.1.3. For fix this, i override abstract fields like this :
<?php namespace App\Entity; … class RefreshToken extends BaseAbstractRefreshToken { … #[ ORM\Column( name: 'refresh_token', type: Types::STRING, nullable: false, ) ] protected $refreshToken; … }
You have to be careful, the original ORM mapping of the package has the $refreshToken
property (refresh_token
column) field mapped as unique and 128 characters long. My mapping looks like this and is not triggering a database change when creating a new migration:
#[
ORM\Column(
name: 'refresh_token',
type: Types::STRING,
length: 128,
unique: true,
nullable: false,
)
]
protected $refreshToken;