[DDC-1928] one-to-one relations mapping Created: 16/Jul/12  Updated: 09/Feb/13  Resolved: 09/Feb/13

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2.2
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Javier Neyra Assignee: Benjamin Eberlei
Resolution: Invalid Votes: 0
Labels: None


 Description   

hello, im new here i dont know if this is the correct place, but try finding help on the web whitout success. so here is my issue.

im trying to map a one to one relation on 2 entities using the id field on both entities.

for example:

i have a customer entity and a cart entity, both entities have only an id field. and there is a FK from cart id to customer id so i make the mappings as follow:

first the customer:

Acme\DemoBundle\Entity\Customer:
type: entity
table: null
oneToOne:
cart:
targetEntity: Cart
mappedBy: customer
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
lifecycleCallbacks: { }

now the cart:

Acme\DemoBundle\Entity\Cart:
type: entity
table: null
oneToOne:
customer:
targetEntity: Customer
inversedBy: cart
joinColumn:
name: id
referencedColumnName: id
fields:
id:
type: integer
id: true

lifecycleCallbacks: { }

the entities get generated ok, but im not able to insert in the cart entity:

im getting the followin exception:

Entity of type Acme\DemoBundle\Entity\Cart is missing an assigned ID for field 'id'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.

when i made the insert a try this two ways:

$cart = new \Acme\DemoBundle\Entity\Cart();
$cart->setId($cart->getId());
$em->persist($cart);
$em->flush();

or this one

$cart = new \Acme\DemoBundle\Entity\Cart();
$cart->setCustomer($customer);
$em->persist($cart);
$em->flush();
in both cases i get the same exception

this is the symfony's log where the insert is generated by doctrine to insert the cart record

[2012-07-16 20:59:06] doctrine.DEBUG: SET NAMES UTF8 ([]) [] []
[2012-07-16 20:59:06] doctrine.DEBUG: INSERT INTO Customer (id) VALUES (null) ([]) [] []
[2012-07-16 20:59:06] event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelException". [] []
[2012-07-16 20:59:06] event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\HttpKernel\EventListener\ExceptionListener::onKernelException". [] []
[2012-07-16 20:59:06] request.CRITICAL: Doctrine\ORM\ORMException: Entity of type Acme\DemoBundle\Entity\Cart is missing an assigned ID for field 'id'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly. (uncaught exception) at /home/javier/intraway/doctrine_test/sf/vendor/doctrine/orm/lib/Doctrine/ORM/ORMException.php line 51 [] []

the only way i get this working is setting the generation strategy to auto but i dont thinks its ok, i want this two entities have the same id and if i make both use generators i cant be surethe ids get generated correctly.

thanks.



 Comments   
Comment by Javier Neyra [ 17/Jul/12 ]

ok. i allmost got it... sorry for the bug post... i was mapping it in the wrong way... i have one remaining issue:

i found this article explaining how to do what i was trying http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity

so i mapped my entities this way:

i have an entity named device report: here is the yml for the entity:

Iway\M2M\ApiBundle\Entity\DeviceReport:
type: entity
table: srv_m2m_device_report
repositoryClass: Iway\M2M\ApiBundle\Entity\DeviceReportRepository

id:
id:
column: reportid
type: integer
generator:
generator:
strategy: SEQUENCE
sequenceGenerator:
sequenceName: srv_m2m_device_report_seq
allocationSize: 10
initialValue: 1

manyToOne:
device:
targetEntity: Device
inversedBy: reports
joinColumn:
name: deviceid
referencedColumnName: deviceid

oneToOne:
battery:
targetEntity: ReportBattery
mappedBy: report
fields:
raw_data:
type: string
length: 4000
creation_date:
type: datetime
data_source:
type: string
length: 16
lifecycleCallbacks: { }

the problem is with the battery entity here is the yml:

Iway\M2M\ApiBundle\Entity\ReportBattery:
type: entity
table: srv_m2m_report_battery
repositoryClass: Iway\M2M\ApiBundle\Entity\ReportBatteryRepository

oneToOne:
report:
targetEntity: DeviceReport
inversedBy: battery
joinColumn:
name: reportid
referencedColumnName: reportid

fields:
report_id:
id: true
type: integer
column: reportid
battery_voltage:
type: integer
external_voltage:
type: integer

lifecycleCallbacks: { }

now here is the thing, i can query without any problem on this two entities and joining works well the problem is when i insert:

here is a simple insert in both entities:

$report = new \Iway\M2M\ApiBundle\Entity\DeviceReport();

$report->setDevice($device);
$report->setRawData("Raw data from EMULATOR");
$report->setCreationDate(new \DateTime("now"));
$report->setDataSource("DEVICE_INFORM");
$em->persist($report);

$battery = new \Iway\M2M\ApiBundle\Entity\ReportBattery();
$battery->setReport($report);
$battery->setReportId($report->getId());
$battery->setBatteryVoltage(10);
$battery->setExternalVoltage(1000);
$em->persist($battery);

$em->flush();

if i dont execute this 2 set Methods the query fails

$battery->setReport($report);
$battery->setReportId($report->getId());

if i only use setReport i get:

[Doctrine\ORM\ORMException]
Entity of type Iway\M2M\ApiBundle\Entity\ReportBattery is missing an assigned ID for field 'report_id'. The identifier generation strategy for this entity requires the ID field to be p
opulated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.

if i only use: setReportId i get

[Doctrine\DBAL\Driver\OCI8\OCI8Exception]
ORA-01400: cannot insert NULL into ("IWAYDATA"."SRV_M2M_REPORT_BATTERY"."REPORTID")

im mapping something in the wrong way but i cant see what it is..... any help would be great!
Thanks

Comment by Javier Neyra [ 17/Jul/12 ]

ok, i want to add a last thing the example http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity

cannot be done using YML (or a least, its not documented)

what i done is get an empty database a used the example just like it is in the article, then used the task provided to pass from one format to the other (using symfony is ./app/console doctrine:mapping:convert yml /path)
and get this 2 yml files:

Acme\DemoBundle\Entity\User:
type: entity
table: User
fields:
id:
type: integer
id: true
generator:
strategy: IDENTITY
lifecycleCallbacks: { }

Acme\DemoBundle\Entity\Address:
type: entity
table: Address
oneToOne:
user:
targetEntity: Acme\DemoBundle\Entity\User
cascade: { }
mappedBy: null
inversedBy: null
joinColumns:
user_id:
referencedColumnName: id
orphanRemoval: false
lifecycleCallbacks: { }

when i try to build my schema with this configuration i get:

[Doctrine\ORM\Mapping\MappingException]
No identifier/primary key specified for Entity 'Acme\DemoBundle\Entity\Address'. Every Entity must have an identifier/primary key.

is there a way to add id: true in a relation on yml or xml configuration? or its only valid using annotations?

Comment by Alexander [ 09/Feb/13 ]

Please use the mailing list or irc channel for support.

Generated at Mon Dec 22 10:45:15 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.