I need to make a simple insertion in the database,
Here is the code in the controller:
public function verifCreateOrder(Request $req){
$store = 1;
$provider =2;
$creation = $creation_start = $req->get('creation_start');
$delivery = $creation_start = $req->get('creation_start');
$em = $this->getDoctrine()->getManager();
$order = new OrderList();
$order->setNumStore($store);
$order->setNumProvider($provider);
$order->setCreation($creation);
$order->setDelivery($delivery);
$em->persist($order);
$em->flush();
die();
return $this->redirectToRoute('search.view');
}
The code of the OrderList entity :
class OrderList
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\ManyToOne(targetEntity="Provider")
* #ORM\JoinColumn(name="num_provider", referencedColumnName="id")
*/
private $numProvider;
/**
* #var int
*
* #ORM\ManyToOne(targetEntity="Store")
* #ORM\JoinColumn(name="num_store", referencedColumnName="id")
*/
private $numStore;
/**
* #return int
*/
public function getNumStore()
{
return $this->numStore;
}
/**
* #param int $numStore
*/
public function setNumStore($numStore)
{
$this->numStore = $numStore;
}
/**
* #var \DateTime
*
* #ORM\Column(name="creation", type="date")
*/
private $creation;
/**
* #var \DateTime
*
* #ORM\Column(name="delivery", type="date")
*/
private $delivery;
/**
* #var \DateTime
*
* #ORM\Column(name="last_update", type="date", nullable=true)
*/
private $lastUpdate;
/**
* #var \DateTime
*
* #ORM\Column(name="emission", type="date", nullable=true)
*/
private $emission;
/**
* #var int
*
* #ORM\Column(name="reduction_1", type="integer", nullable=true)
*/
private $reduction1;
/**
* #var int
*
* #ORM\Column(name="reduction_2", type="integer", nullable=true)
*/
private $reduction2;
/**
* #var string
*
* #ORM\Column(name="comment", type="string", nullable=true, length=255)
*/
private $comment;
Here is the error returned by symfony:
Expected value of type "AppBundle\Entity\Provider" for association field "AppBundle\Entity\OrderList#$numProvider", got "integer" instead.
Please help me resolve this error.
You are mixing the Doctrine relation and database foreign key concepts (they are very close, but not the same). The problem is that you can't treat related entity identifier as related entity in Doctrine. You need to pass whole related entity and not just foreign key.
There are at least two solutions:
Instead of passing identifier of store (1) and identifier of provider (2), firstly retrieve this entities from the database ($em->find(...)).
You can trick doctrine with getReference method, that should return you a proxy of needed object with id ($em->getReference('Path\To\Store', 1 and $em->getReference('Path\To\Provider', 2).
If you want more information, you can check these docs: reference proxies and relations.
public function verifyCreateOrder(Request $req){
$storeId = 1;
$providerId = 2;
$creation = $creation_start = $req->get('creation_start');
$delivery = $creation_start = $req->get('creation_start');
$em = $this->getDoctrine()->getManager();
// getting references
$store = $em->getReference(Store::class, $storeId);
$provider = $em->getReference(Provider::class, $providerId);
$order = new OrderList();
$order->setNumStore($store);
$order->setNumProvider($provider);
$order->setCreation($creation);
$order->setDelivery($delivery);
$em->persist($order);
$em->flush();
die();
return $this->redirectToRoute('search.view');
}
I am also new to php but, you set $provider to be a integer = 2, and your relation expect object Provider $provider.
Related
Job entity has a property called candidates which is an array of Users and it is not mapped or related to any other entity.On given route we fetch specific Job object by id.We update our candidates array by assigning the user who we get from the current session.It turns out that the user is being saved, but on each call we lose those users which had been saved before.
Why does that happen?
/**
* #Route("/job/apply/{id}", requirements={"id"="\d+"}, name="student_candidate", methods={"POST"})
*
* #param int $id
*
* #return JsonResponse
*/
public function apply(int $id)
{
$job = $this->getDoctrine()->getRepository(Job::class)->find($id);
$candidate = $this->getUser();
$job->addCandidate($candidate);
$this->getDoctrine()->getManager()->flush();
return new JsonResponse([
'status' => 'success',
'message' => 'some_success_message'
]);
}
class Job
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="content", type="text", length=65535)
*/
private $content;
/**
* #var User[]|ArrayCollection
*/
private $candidates;
public function __construct()
{
$this->candidates = new ArrayCollection();
}
/**
* #return User[]|ArrayCollection
*/
public function getCandidates()
{
return $this->candidates;
}
/**
* #param User $user
*
* #return Job
*/
public function addCandidate(User $user)
{
$this->candidates[] = $user;
return $this;
}
}
I try to get all my objects DemandCab with their children object (DecisionCab).
My 2 entities
/**
* DemandCab.
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="DemandCabRepository")
*/
class DemandCab
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var DecisionCab
*
* #ORM\OneToMany(targetEntity="\My\CabBundle\Entity\DecisionCab", mappedBy="demandCab")
*/
private $decisionsCab;
/**
* #var \DateTime
*
* #ORM\Column(name="startDate", type="datetime")
*/
private $startDate;
/**
* #var \DateTime
*
* #ORM\Column(name="endDate", type="datetime", nullable=true)
*/
private $endDate;
/**
* #var int
*
* #ORM\Column(name="followup", type="integer", nullable=true)
*/
private $followup;
/**
* #var InfoCab
*
* #ORM\ManyToOne(targetEntity="\My\CabBundle\Entity\InfoCab", inversedBy="demandsCab")
*/
private $infoCab;
}
/**
* DecisionCab.
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="DecisionCabRepository")
*/
class DecisionCab
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var DemandCab
*
* #ORM\ManyToOne(targetEntity="\My\CabBundle\Entity\DemandCab", inversedBy="decisionsCab")
*/
private $demandCab;
/**
* #var bool
*
* #ORM\Column(name="decision", type="boolean", nullable=true)
*/
private $decision;
/**
* #var string
*
* #ORM\Column(name="motif", type="string", length=500, nullable=true)
*/
private $motif;
/**
* #var string
*
* #ORM\Column(name="role", type="string", length=255)
*/
private $role;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime", nullable=true)
*/
private $date;
/**
* #var DemandCab
*
* #ORM\ManyToOne(targetEntity="\My\CabBundle\Entity\DemandCab", inversedBy="decisionsCab")
*/
private $demandCab;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="\My\CabBundle\Entity\User", inversedBy="decisionsCab")
*/
private $user;
}
In my DemandCabRepository
public function findAllCompleted(){
$qb = $this->createQueryBuilder("dem");
$qb->select('dem, dec');
$qb->leftJoin("dem.decisionsCab", "dec");
$qb->andWhere("dem.completed = 1");
$qb->orderBy("dem.startDate", "DESC");
return $qb->getQuery()->getResult();
}
My DemandCab data
My DecisionCab data
When i dump result, only 2 decisions appear ...
... whereas when i use getArrayResult, i have my 4 decisions ...
The query is good but i dont understand why hydration remove DecisionCab object with attribute decision at 0 or 1 (only null are display).
I would like to understand why and is there a solution to get DemandCab object with all DecisionCab children object.
Thanks
I am able to reproduce your issue, but I am not sure if this is your case.
Anyway, my assumption is that you query the demand Entity joined with decision relation at least once with the help of a query builder. Maybe this is done in your action, in an event listener or somewhere else in your code.
So you may have something like:
$qb = $this->getDoctrine()
->getRepository(DemandCab::class)->createQueryBuilder("dem");
$qb->select('dem, dec');
$qb->leftJoin("dem.decisionsCab", "dec");
$qb->andWhere("dec.decision IS NULL");
$qb->orderBy("dem.startDate", "DESC");
$results = $qb->getQuery()->getResult(); // <-- the decisionsCab collection is hydrated but filtered
$qb2 = $this->getDoctrine()
->getRepository(DemandCab::class)->createQueryBuilder("dem");
$qb2->select('dem, dec');
$qb2->leftJoin("dem.decisionsCab", "dec");
$qb2->andWhere("dem.completed = 1");
$qb2->orderBy("dem.startDate", "DESC");
$q = $qb2->getQuery();
//$q->setHint(Query::HINT_REFRESH, true);
$results = $q->getResult();
The issue is in Doctrine\ORM\Internal\Hydration\ObjectHydrator, it has the property "initializedCollections" where already initialized collections are kept and the collections are hashed by the parent entity type and the entity itself. Unfortunately in the above case, the heydrator does not understand that the collection is filtered in the 1st query and uses it in the 2nd query in order to avoid rehydration.(github link)
The solution is to cause the query builder to refresh. Try the code:
$qb->orderBy("dem.startDate", "DESC");
$q = $qb->getQuery();
$q->setHint(Query::HINT_REFRESH, true); // <-- Tell the hydrator to refresh
return $q->getResult();
First you have initialize your class with the relation ManyToOne with an ArrayCollection.
And you don't need any of this 'DemandCabRepository'. All the work is done by Doctrine
I have a problem with a query in doctrine i started using Symfony recently for to be continued a old project in Symfony and now i want learn it.
I start to explain from db and i write only the fields that interest me :
user(id,name,surname,phat)
user_reference(id,id_user[FOREIGN KEY id FROM user],id_user_referenced[FOREIGN KEY id FROM user])
This is the query :
$id_user = $user->getId();
$query = $em->createQueryBuilder()
->select('ur','uu')
->from('DtEcBundle:UserReferences', 'ur')
->innerJoin("ur.id_user","uu")
->where("ur.id_user = :id_user")
->setParameter("id_user",$id_user)
->getQuery();
$userpyramid = $query->getResult();
I print in my twig file id_user_referenced but i would print too "name, surname and path" from USER table
For print id_user_referenced in the Entity UserReferences there is this code:
/**
* Set id_user_referenced
*
* #param \Dt\EcBundle\Entity\User $idUserReferenced
* #return UserReferences
*/
public function setIdUserReferenced(\Dt\EcBundle\Entity\User $idUserReferenced = null) {
$this->id_user_referenced = $idUserReferenced;
return $this;
}
/**
* Get id_user_referenced
*
* #return \Dt\EcBundle\Entity\User
*/
public function getIdUserReferenced() {
return $this->id_user_referenced;
}
Transform a number like id to string in Entity User with:
public function __toString(){
return strval($this->id);
}
Now if i add to my query in the select this:
->select('ur','uu.path')
Symfony send me an error:
Key "idUserReferenced" for array with keys "0, path" does not exist in
DtEcBundle:Profilo:digitalpr-profile.html.twig at line 40
Why?? How can i solved it??
UserReferences.php
namespace Dt\EcBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* UserReferences
*
* #ORM\Table(name="user_references" ,uniqueConstraints= {#ORM\UniqueConstraint(name="recension_unique", columns={"id_user", "id_user_referenced"})})
* #ORM\Entity(repositoryClass="Dt\EcBundle\Entity\UserReferencesRepository")
*/ class UserReferences {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #var Dt\EcBundle\Entity\User
* #ORM\ManyToOne(targetEntity="Dt\EcBundle\Entity\User", inversedBy="references")
* #ORM\JoinColumn(name="id_user", referencedColumnName="id")
*/
private $id_user;
/**
* #ORM\ManyToOne(targetEntity="Dt\EcBundle\Entity\User")
* #ORM\JoinColumn(name="id_user_referenced", referencedColumnName="id")
* */
private $id_user_referenced;
/**
*
* #var string
* #ORM\Column(name="reference", type="text", nullable=false,unique=false);
*/
private $reference;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set reference
*
* #param string $reference
* #return UserReferences
*/
public function setReference($reference) {
$this->reference = $reference;
return $this;
}
/**
* Get reference
*
* #return string
*/
public function getReference() {
return $this->reference;
}
/**
* Set id_user
*
* #param \Dt\EcBundle\Entity\User $idUser
* #return UserReferences
*/
public function setIdUser(\Dt\EcBundle\Entity\User $idUser = null) {
$this->id_user = $idUser;
return $this;
}
/**
* Get id_user
*
* #return \Dt\EcBundle\Entity\User
*/
public function getIdUser() {
return $this->id_user;
}
/**
* Set id_user_referenced
*
* #param \Dt\EcBundle\Entity\User $idUserReferenced
* #return UserReferences
*/
public function setIdUserReferenced(\Dt\EcBundle\Entity\User $idUserReferenced = null) {
$this->id_user_referenced = $idUserReferenced;
return $this;
}
/**
* Get id_user_referenced
*
* #return \Dt\EcBundle\Entity\User
*/
public function getIdUserReferenced() {
return $this->id_user_referenced;
}
}
User.php
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, unique=false, nullable=false)
* #Assert\NotBlank(message="user.name.not.blank")
* #Assert\Length(
* min=2,
* max=150,
* minMessage="user.name.not.min",
* maxMessage="user.name.not.max" )
*/
protected $name;
/**
* #var string
*
* #ORM\Column(name="surname", type="string", length=255, unique=false, nullable=false)
* #Assert\NotBlank(message="user.surname.not.blank")
* #Assert\Length(
* min=2,
* max=150,
* minMessage="user.surname.not.min",
* maxMessage="user.surname.not.max" )
*/
protected $surname;
/**
* #var \DateTime
* #ORM\Column(name="borndate", type="datetime",unique=false,nullable=false)
*/
protected $borndate;
/**
*
* #var string
* #ORM\Column(name="tel", type="string",length=50, unique=true,nullable=true)
* #Assert\Regex("/[0-9]/")
*/
protected $tel;
/**
*
* #var string
* #ORM\Column(name="city", type="string",length=255,unique=false,nullable=true)
* #Assert\NotBlank(message="user.expert.city.not.blank",groups={"Expert"})
* #Assert\NotBlank(message="user.expert.city.not.blank",groups={"ExpertProfile"})
* #Assert\Length(
* min=2,
* max=150,
* minMessage="user.expert.city.not.min",
* maxMessage="user.expert.city.not.max", groups={"Expert"} )
* #Assert\Length(
* min=2,
* max=150,
* minMessage="user.expert.city.not.min",
* maxMessage="user.expert.city.not.max", groups={"ExpertProfile"} )
*/
protected $city;
/**
*
* #var string
* #ORM\Column(name="street", type="string",length=255,unique=false,nullable=true)
* #Assert\NotBlank(message="user.expert.street.not.blank",groups={"Expert"})
* #Assert\NotBlank(message="user.expert.street.not.blank",groups={"ExpertProfile"})
* #Assert\Length(
* min=2,
* max=150,
* minMessage="user.expert.street.not.min",
* maxMessage="user.expert.street.not.max", groups={"Expert"} )
* #Assert\Length(
* min=2,
* max=150,
* minMessage="user.expert.street.not.min",
* maxMessage="user.expert.street.not.max", groups={"ExpertProfile"} )
*/
protected $street;
/**
*
* #var type
*
* #Assert\File(
* maxSize = "1024k",
* mimeTypes = {"image/gif","image/jpeg","image/pjpeg","image/png"},
* mimeTypesMessage = "user.image.mimetypes",
* maxSizeMessage = "user.image.maxsize"
* )
* #Assert\NotBlank(message="user.expert.mandatory.photo",groups={"Expert"})
*
*/
protected $photo;
/**
* #ORM\Column(name="photo_path",type="string", length=255, nullable=true,unique=true)
*/
protected $path;
/**
* Membri per la gestione dei file
*
*/
The problem is that doctrine hydrates your result in Array Hydration mode, while you expect Object Hydraion.
In the first case you ask for 2 related objects and doctrine can link them. In the second you ask for an object and for a scalar value, and doctrine cannot link them, so it returns them in two separate fields of an result array.
So the result that you have got from $query->getResult() in case of select('ur','uu.path') is not an array of User objects, but an array of 2 fields - $result[0] where you have all found User objects, and $result['path'] for uu.path - because uu.path is scalar value rather than object.
So you need to make select('ur','uu') and address your result as $result->getIdUserReferenced()->getPath().
Or (if you want to save some resources, but I don't think it worth it) make select('ur','uu.path') and then make var_dump of result. And you will see how to address to what you need.
I try in this mode but is not good
$id_user = $user->getId();
$query = $em->createQueryBuilder()
->select('ur','uu')
->from('DtEcBundle:UserReferences', 'ur')
->innerJoin("ur.id_user","uu")
->where("ur.id_user = :id_user")
->setParameter("id_user",$id_user)
->getQuery();
$userpyramid = $query->getResult();
$form = $this->get('form.factory')->createNamedBuilder('form', 'form')
->setMethod('POST')
->setAction($this->generateUrl('profilo_secondlevel'))
->add('save', 'submit', ['label' => 'Prova'])
->getForm();*/
$result->getIdUserReferenced()->getPath();
return $this->render('DtEcBundle:Profilo:index.html.twig', array(
'user' => $user,
'tags' => $tags,
'followers' =>$followers,
'expert' =>$expert,
'user_expert' =>$user_expert,
'well_cat' =>$well_cat,
'user_notification' => $user_notifications,
"udputenti" => $udputenti,
"userpyramid" => $userpyramid,
"result"=> $result
//'form'=>$form->createView()
));`
I have problem with updating one-to-one bidirectional association.
User Entity
/**
*
* #ORM\Table(name="test_user")
*/
class User
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="login", type="string", length=32, nullable=false, unique=true)
*/
private $login;
/**
*
* #ORM\OneToOne(targetEntity="Points", mappedBy="user", cascade={"persist"})
*/
private $points;
...
/**
* Set points
*/
public function setPoints(array $points)
{
$this->points = new Points($points);
$this->points->setUser($this);
return $this;
}
/**
* Get points
*/
public function getPoints()
{
return $this->points;
}
}
Points Entity
/**
* Points
*
* #ORM\Table(name="test_user_points")
* #ORM\Entity
*/
class Points {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var integer
*
* #ORM\Column(type="integer", nullable=false)
*/
private $points;
/**
* #var string
*
* #ORM\Column(name="period", type="string", length=24)
*/
private $period;
/**
* #var User
*
* #ORM\OneToOne(targetEntity="User", inversedBy="points")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id",onDelete="CASCADE", nullable=false)
*/
private $user;
/**
* Constructor
*/
public function __construct(array $params = array())
{
$hydrator = new MyHydrator();
$hydrator->hydrate($params, $this);
}
...
/**
* Set user
*
* #param User $user
*/
public function setUser(User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return User
*/
public function getUser()
{
return $this->user;
}
}
Class MyHydrator is converting from array(first param) to object(second param). It is very important and I have to use it.
My save function looks like this:
public function save(array $data)
{
...
// This is how my input data looks
$data = array(
'login' => 'Test',
array(
'points' => 999,
'period' => 'monthly'
)
);
if ($userExists) {
// UPDATE
$hydrator = new MyHydrator();
$hydrator->hydrate($data, $userExists);
$this->em->persist($userExists);
$this->em->flush();
} else {
// INSERT
$user = new User($data);
$this->em->persist($user);
$this->em->flush();
}
}
Inserting to database works perfect, but when I try to update record I get error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '4' for key 'UNIQ_DAD93D6EA76ED395'
4 is a value of user_id column in points table
How can I edit existing record without error about duplicate id?
It's old but since I encoutered a similar issue, I resolved it this way :
in User
public function setPoints($points)
{
if ($this->points !== null) {
$this->points->setUser(null);
}
$this->points = $points;
$points->setUser($this);
}
I have an Entity with a primary key like this:
/**
* #var integer
*
* #ORM\Column(name="product_id", type="integer", nullable=false)
* #ORM\Id
*/
protected $productId;
....
/**
* Set productId
*
* #param integer $productId
* #return Products
*/
public function setProductId($productId)
{
$this->productId = $productId;
return $this;
}
/**
* Get productId
*
* #return integer
*/
public function getProductId()
{
return $this->productId;
}
But when I try to insert an ProductId with set method, I get this error:
integrity constraint violation 1062 duplicate entry '0' for key 'primary'
I tried with * #ORM\GeneratedValue(strategy="NONE") but the result it's the same, I need to set the Product Id because the sequence isn't 1, 2, 3... is different.
And I can't create a new Id because my current ProductId is used by other entities like Foreing Keys.
Any solution?
Thanks in advance.
-----Edit with the file where I have the error-----
$prod = new Products();
$prod->setProductId("65");
$manager->persist($prod);
$manager->flush();
----Edit with whole Entity----
namespace My\WebBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Products
{
/**
* #var integer
*
* #ORM\Column(name="product_id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
protected $productId;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=50, nullable=false)
*/
private $name;
/**
* #var integer
*
* #ORM\Column(name="version", type="integer", nullable=true)
*/
private $version;
/**
* #var string
*
* #ORM\Column(name="code", type="string", length=10, nullable=false)
*/
private $code;
/**
* #var integer
*
* #ORM\Column(name="price", type="integer", nullable=false)
*/
private $price;
/**
* Set productId
*
* #param integer $productId
* #return Products
*/
public function setProductId($productId)
{
$this->productId = $productId;
return $this;
}
/**
* Get productId
*
* #return integer
*/
public function getProductId()
{
return $this->productId;
}
/**
* Set name
*
* #param string $name
* #return Products
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set version
*
* #param integer $version
* #return Products
*/
public function setVersion($version)
{
$this->version = $version;
return $this;
}
/**
* Get version
*
* #return integer
*/
public function getVersion()
{
return $this->version;
}
/**
* Set code
*
* #param string $code
* #return Products
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* Set price
*
* #param integer $price
* #return Products
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return integer
*/
public function getPrice()
{
return $this->price;
}
When using no identifier generation strategy you should not forget that you have to assign the custom ID before you call EntityManagers persist() method.
I think you are persisting the new Entity before assigning the custom ID which means your $productId property is set to null and will be casted to 0 (zero) if you try to flush it. That will cause your error.
Doctrine Doc
Marcus post a good answer to your problem. You can solve it by adding id into you Entity, and use productId as secondary key.
Add id and set it to Auto increment, like
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
Then you can use your productId with:
/**
* #var integer
*
* #ORM\Column(name="product_id", type="integer", nullable=false)
*/
protected $productId;
With this solution you will use $productId as secondary key. Don't forget to clear data in your table.
You also have an error here:
$prod->setProductId(65);
Now you try set data which is string - in your table is integer.