Actually... more or less I know where is my problem.
I'm receiving this error in a particular controller where I try to persist($object)
...
Actually I'm developing a webapp for me to have a register to all my books I'm reading.. and I use Google Books API for that. So, I have the next Entities:
- Admin
- Users
- Books
- Categories
I was thinking about the db
and I wanted a table with user_id, book_id
so I decided to do a ManyToMany
but, I don't know if this is the way.. or not. (Because my familiars are going to use it)
It has to be like many users can have the same book and a user can have many books obviusly.
So, the error I'm getting I guess it's because I'm not implementing well done the ManyToMany...
I write below the Controller
and Entities
Where Users is like:
/**
* @ORM\Entity
* @ORM\Table(name="Users")
* @ORM\Entity(repositoryClass="UsersRepository")
* @UniqueEntity("username")
* @UniqueEntity("email")
*/
class Users implements UserInterface, \Serializable
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $name;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $lastname;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $username;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank()
* @Assert\Email()
*/
private $email;
/**
*
* @Assert\Length(max=4096)
*/
private $plainPassword;
/**
*
* @ORM\Column(type="string", length=64)
*/
private $password;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $language;
/**
* @ORM\Column(type="boolean")
*/
private $isActive;
/*****************
* Users constructor.
*/
public function __construct() {
$this->language = 'es';
$this->isActive = true;
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return mixed
*/
public function getLastname()
{
return $this->lastname;
}
/**
* @param mixed $lastname
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
}
/**
* @return mixed
*/
public function getUsername()
{
return $this->username;
}
/**
* @param mixed $username
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* @param mixed $email
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* @return mixed
*/
public function getPlainPassword()
{
return $this->plainPassword;
}
/**
* @param mixed $plainPassword
*/
public function setPlainPassword($plainPassword)
{
$this->plainPassword = $plainPassword;
}
/**
* @return mixed
*/
public function getPassword()
{
return $this->password;
}
/**
* @param mixed $password
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* @return mixed
*/
public function getLanguage()
{
return $this->language;
}
/**
* @param mixed $language
*/
public function setLanguage($language)
{
$this->language = $language;
}
/**
* @return mixed
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* @param mixed $isActive
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
}
//implementaciones de la interface
public function getSalt()
{
// you *may* need a real salt depending on your encoder
// see section on salt below
return null;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function eraseCredentials()
{
}
/** @see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
$this->isActive,
));
}
/** @see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
$this->isActive,
) = unserialize($serialized);
}
}
and Books is like:
/**
* @ORM\Entity
* @ORM\Table(name="Book")
* @ORM\Entity(repositoryClass="BookRepository")
*/
class Book
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $title;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $author;
/**
* @ORM\Column(type="text")
*/
private $language;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $genre;
/**
* @ORM\Column(type="integer")
* @Assert\NotBlank()
*/
private $price;
/**
* @ORM\Column(type="text")
*/
private $pages;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $synopsis;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $rate;
/**
* @ORM\Column(type="text")
*/
private $id_google;
/**
* @ORM\ManyToMany(targetEntity="Users", mappedBy="books")
*/
private $users;
/*****************
* Book constructor.
*/
public function __construct() {
$this->users = new ArrayCollection();
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}
/**
* @param mixed $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return mixed
*/
public function getAuthor()
{
return $this->author;
}
/**
* @param mixed $author
*/
public function setAuthor($author)
{
$this->author = $author;
}
/**
* @return mixed
*/
public function getLanguage()
{
return $this->language;
}
/**
* @param mixed $language
*/
public function setLanguage($language)
{
$this->language = $language;
}
/**
* @return mixed
*/
public function getGenre()
{
return $this->genre;
}
/**
* @param mixed $genre
*/
public function setGenre($genre)
{
$this->genre = $genre;
}
/**
* @return mixed
*/
public function getPrice()
{
return $this->price;
}
/**
* @param mixed $price
*/
public function setPrice($price)
{
$this->price = $price;
}
/**
* @return mixed
*/
public function getPages()
{
return $this->pages;
}
/**
* @param mixed $pages
*/
public function setPages($pages)
{
$this->pages = $pages;
}
/**
* @return mixed
*/
public function getSynopsis()
{
return $this->synopsis;
}
/**
* @param mixed $synopsis
*/
public function setSynopsis($synopsis)
{
$this->synopsis = $synopsis;
}
/**
* @return mixed
*/
public function getRate()
{
return $this->rate;
}
/**
* @param mixed $rate
*/
public function setRate($rate)
{
$this->rate = $rate;
}
/**
* @return mixed
*/
public function getIdGoogle()
{
return $this->id_google;
}
/**
* @param mixed $id_google
*/
public function setIdGoogle($id_google)
{
$this->id_google = $id_google;
}
/**
* @return mixed
*/
public function getUsers()
{
return $this->users;
}
/**
* @param mixed $users
*/
public function setUsers(Users $users = null)
{
$this->users = $users;
}
/**
* Add user
*
* @param \AppBundle\Entity\Users $user
*
* @return Book
*/
public function addUser(Users $user)
{
$this->users[] = $user;
return $this;
}
/**
* Remove user
*
* @param \AppBundle\Entity\Users $user
*/
public function removeUser(Users $user)
{
$this->users->removeElement($user);
}
}
LibraryController
class LibraryController extends BaseController
{
private $APIkey = "&key=" . "AIzaSyAN638WbYe1vOfGya989p7ZbfXnPzBLfkg";
/**
* @Route ("/libreria", name="libreria")
*/
public function getLibreria(){
$securityContext = $this->container->get('security.authorization_checker');
if ($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
$em = $this->getDoctrine()->getManager();
$user = $this->get('security.token_storage')->getToken()->getUser();
$this->addData('user', $user);
return $this->render('AppBundle:libreria:libreria.html.twig', $this->getData());
}
return $this->redirect("login");
}
/**
* Adds to the library the requested book
* @Route ("/libreria/addBook/{id_google}", name="addBook")
*/
public function addBook($id_google){
$securityContext = $this->container->get('security.authorization_checker');
if ($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
$em = $this->getDoctrine()->getManager();
$user = $this->get('security.token_storage')->getToken()->getUser();
$infoBook = $this->getBookFromAPI($id_google); // Cogemos toda la información del libro en cuestión
$vInfo = $infoBook['volumeInfo']; // Para ahorrarnos código y usar este subarray de manera practica
$book = new Book();
/**
* Hacemos los seters pertinentes para poner el contenido en el libro
* y dejarlo listo para poder hacer un flush
*/
$book->setTitle($vInfo['title']);
$book->setAuthor($vInfo['authors'][0]);
$book->setLanguage($vInfo['language']);
$book->setGenre($vInfo['categories'][0]);
$book->setPrice($infoBook['saleInfo']['retailPrice']['amount']);
$book->setPages($vInfo['printedPageCount']);
$book->setSynopsis($vInfo['description']);
if($vInfo['averageRating']){
$book->setRate($vInfo['averageRating']);
}
$book->setIdGoogle($id_google);
$book->setUsers($user);
// Guardamos el libro en la bbdd
$em->persist($book);
$em->flush();
$this->sendResponseStatus('OK');
// Generamos los datos para la respuesta ajax
return new JSONResponse($this->getData());
}
return $this->redirect("login");
}
// Coge la información de un libro gracias a su id
public function getBookFromAPI($id){
// Instancia del BuzzBundle para peticiones HTTP externas
$buzz = $this->container->get('buzz');
// Resultado de la peticion HTTP 'GET'
$responseAPI = $buzz->get('https://www.googleapis.com/books/v1/volumes/'.$id);
$jsonLibro = $responseAPI->getContent();
return $this->transformarStringToArray($jsonLibro);
}
// Se usa para hacer que el String devuelto por la API de Google sea un array
public function transformarStringToArray($string){
$stringDecoded = json_decode($string);
$array = json_decode(json_encode($stringDecoded), true);
return $array;
}
}
So, the error appears I guess when I try to persist the db
because there is something bad implemented...
Any clue or solution?
Thanks to everyone! Have a nice day!
Victor
No
$book->setUsers($user);
but$book->addUser($user);
And, in general, method
setUsers
is not validYou must not redefine this property after being initialized in the constructor. You can only add or remove elements from it, but assigning new value will break doctrine's functionality.