pink-tie / JMSSerializerServiceProvider

Silex Service Provider for the JMSSerializerBundle
MIT License
11 stars 11 forks source link

Using Doctrine Entity #3

Closed amenophis closed 12 years ago

amenophis commented 12 years ago

Hi, I've would to use this Provider with this other one (https://github.com/Amenophis/silex-doctrineorm) i've developped.

So when i use the $this->app['serializer']->serialize($items, 'json'), i got an error on my entities : AnnotationException: [Semantical Error] The annotation "@Entity" in class Scrilex\Entity\Project was never imported. Did you maybe forget to add a "use" statement for this annotation?

Any idea ?

marijn commented 12 years ago

Annotations are references to classes. So when your doc block contains an annotation @Entity it tries to load the Entity class. Since it's not loaded, you should add a use statement for that annotation.

You can refer to the Symfony Documentation on Doctrine Entity mapping for a good example. There you see an example where the ORM Mapping entities are imported using use Doctrine\ORM\Mapping as ORM; and referred to in the docblocks as @ORM\Entity.

amenophis commented 12 years ago

This is my code after add annotations Prefix

/* * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") * @ORM\Column(type="integer") * @JMS\Type("integer") */ protected $id;

I got this error while it worked properly before use JMS Serializer :

MappingException: No identifier/primary key specified for Entity "Scrilex\Entity\Project" sub class of "". Every Entity must have an identifier/primary key.

amenophis commented 12 years ago

Sorry, i missed an annotation, but i got this error: MappingException: Class "Scrilex\Entity\Task" sub class of "" is not a valid entity or mapped super class.

<?php

namespace Scrilex\Entity;

use Doctrine\ORM\Mapping as ORM;
use JMS\SerializerBundle\Annotation as JMS;

/**
 * @ORM\Entity(repositoryClass="Scrilex\Entity\TaskRepository")
 * @ORM\Table(name="task")
 */
class Task {

    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Project", inversedBy="tasks")
     */
    protected $project;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="tasks")
     */
    protected $user;

    /**
     * @ORM\Column(type="integer")
     */
    protected $pos;

    /**
     * @ORM\Column(type="integer", nullable=false)
     */
    protected $col;

    /**
     * @ORM\Column(type="integer", nullable=false)
     */
    protected $severity;

    /**
     * @ORM\Column(type="string", nullable=false)
     */
    protected $content;

    /**
     * @ORM\OneToMany(targetEntity="Task", mappedBy="task")
     * @ORM\OrderBy({"created_at" = "ASC"})
     */
    protected $histories;

    public function getId() { return $this->id; }
    public function getProject() { return $this->project; }
    public function getUser() { return $this->user; }
    public function getPos() { return $this->pos; }
    public function getCol() { return $this->col; }
    public function getSeverity() { return $this->severity; }
    public function getContent() { return $this->content; }

    public function setId($id) { $this->id = $id; return $this; }
    public function setProject($project) { $this->project = $project; return $this; }
    public function setUser($user) { $this->user = $user; return $this; }
    public function setPos($pos) { $this->pos = $pos; return $this; }
    public function setCol($col) { $this->col = $col; return $this; }
    public function setSeverity($severity) { $this->severity = $severity; return $this; }
    public function setContent($content) { $this->content = $content; return $this; }
}
marijn commented 12 years ago

@Amenophis I'm not really sure what is going wrong. What I do know is that these are exceptions caused by incorrect Doctrine mapping. Hence, you best try to get support on the doctrine IRC channel or the doctrine mailing list.

If you push your current code to Github, I'm willing to have a look at it quickly.

amenophis commented 12 years ago

The problem were in my code, now I got this error :

Fatal error: Uncaught exception 'Doctrine\Common\Annotations\AnnotationException' with message '[Semantical Error] The annotation "@JMS\SerializerBundle\Annotation\Type" in property Amenophis\UserAdmin\Entity\User::$id does not exist, or could not be auto-loaded.' in D:\wamp\www\Scrilex\vendor\doctrine\common\lib\Doctrine\Common\Annotations\AnnotationException.php on line 52

What is wrong ?

<?php

namespace Amenophis\UserAdmin\Entity;

use \Symfony\Component\Security\Core\User\UserInterface;

use Doctrine\ORM\Mapping as ORM;
use JMS\SerializerBundle\Annotation as JMS;

// foo : 5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg==
// array('ROLE_ADMIN') : a:1:{i:0;s:10:"ROLE_ADMIN";}

/**
 * @ORM\Entity(repositoryClass="Scrilex\Entity\UserRepository")
 * @ORM\Table(name="user")
 */
abstract class User implements UserInterface, \Serializable {

    public static $enumRoles = array(
        'ROLE_ADMIN' => 'ROLE_ADMIN',
        'ROLE_MANAGER' => 'ROLE_MANAGER',
        'ROLE_USER' => 'ROLE_USER'
    );

    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     * 
     * @JMS\Type("integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=32, unique=true, nullable=false)
     * 
     * @JMS\Type("string")
     */
    protected $username;

    /**
     * @ORM\Column(type="string", length=255, nullable=false)
     */
    protected $password;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string salt
     */
    protected $salt;

    /**
     * @ORM\Column(type="string", nullable=false)
     * 
     * @JMS\Type("string")
     */
    protected $firstname;

    /**
     * @ORM\Column(type="string", nullable=false)
     * 
     * @JMS\Type("string")
     */
    protected $lastname;

    /**
     * @ORM\Column(type="array")
     * 
     * @JMS\Type("array")
     */
    protected $roles;

    public function __construct()
    {
        $this->roles = array();
        $this->tasks = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Compares this user to another to determine if they are the same.
     * 
     * @param UserInterface $user The user
     * @return boolean True if equal, false othwerwise.
     */
    public function equals(UserInterface $user)
    {
        return md5($this->getUsername()) == md5($user->getUsername());
    }

    public function getId() { return $this->id; }
    public function getUsername() { return $this->username; }
    public function getFirstname() { return $this->firstname; }
    public function getLastname() { return $this->lastname; }
    public function getPassword() { return $this->password; }
    public function getSalt() { return null; }
    public function getRoles(){ return $this->roles; }

    public function setId($id) { $this->id = $id; return $this; }
    public function setUsername($username) { $this->username = $username; return $this; }
    public function setFirstname($firstname) { $this->firstname = $firstname; return $this; }
    public function setLastname($lastname) { $this->lastname = $lastname; return $this; }
    public function setPassword($password) { $this->password = $password; return $this; }
    public function setSalt($salt) { return $this; }
    public function setRoles($roles) { $this->roles = $roles; return $this; }

    public function eraseCredentials() { return true; }

    public function serialize($array = array()) {
        $array['username'] = $this->username;
        $array['password'] = $this->password;
        $array['lastname'] = $this->lastname;
        $array['firstname'] = $this->firstname;
        return serialize($array);
    }

    public function unserialize($data) {
        $datas = unserialize($data);
        $this->username = $datas['username'];
        $this->password = $datas['password'];
        $this->lastname = $datas['lastname'];
        $this->firstname = $datas['firstname'];
    }
}
marijn commented 12 years ago

Have you cleared your cache?

amenophis commented 12 years ago

I removed /cache/serializer content, but the problem is the same ...

amenophis commented 12 years ago

You can get code here : https://github.com/Amenophis/Scrilex

marijn commented 12 years ago

How is your autoloader configured? Have you installed via composer? It seems you are using the right class reference but the autoloader is unable to load the class file.

marijn commented 12 years ago

There is no composer file available in that repository…

amenophis commented 12 years ago

gitignore error ...

It's now OK !

marijn commented 12 years ago

I'm sorry. I took a quick look but couldn't detect any anomalies. My schedule doesn't allow me to assist you further at the moment. Perhaps you can check the Symfony IRC channel on freenode (#symfony).

When I have time to look at it I'll check back with you.

amenophis commented 12 years ago

Thanks for helping me !

amenophis commented 11 years ago

Hi, did you look for my problem ?

Thanks !

amenophis commented 11 years ago

I find a way to make it works !

in app.php

require_once __DIR__ . '/../vendor/autoload.php';

//Add the line below: It Works !
$t = new JMS\SerializerBundle\Annotation\Type(array('value' => 'string'));

$app = new Silex\Application();

Any idea ?

marijn commented 11 years ago

It seems the autoloader is not properly registered. See the doctrine documentation for more info.

marijn commented 11 years ago

I've opened a ticket (#4) to document this better for other users. Sorry for the inconvenience.

amenophis commented 11 years ago

How can i help you with this issue ?

amenophis commented 11 years ago

If i add some code here in the provider,

$app['serializer.metadata.annotation_reader'] = $app->share(function () use ($app) {
    die("here");
    AnnotationRegistry::registerAutoloadNamespace("JMS\SerializerBundle\Annotation", $app['serializer.src_directory']);

    return new AnnotationReader();
});

The execution is not stopped, so the method is not called ...

marijn commented 11 years ago

Is your code requesting the $app['serializer'] service?

amenophis commented 11 years ago

Yes, If i put var_dump($namespace); at the top of registerAutoloadNamespace in AnnotationRegistry class, i just see :

string 'Doctrine\ORM\Mapping' (length=20)

JMS namespace not seems not to be registered ...

tulanowski commented 11 years ago

@Amenophis your problem is caused by using wrong namespace. Use use JMS\Serializer\Annotation as JSM; instead of use JMS\SerializerBundle\Annotation as JSM;

... something has changed between versions.

bidczak commented 11 years ago

Hi

I was following example in readme and I had similar problem with 'The annotation xxx in class xxx was never imported'. My solution was to change serializer.src_directory to 'path/to/vendor/jms/serializer-bundle' (notice I have removed '/src' at the end).

Maybe you should fix example in readme?