DDC-1928: one-to-one relations mapping #2597

Closed
doctrinebot opened this Issue Jul 16, 2012 · 4 comments

2 participants

@doctrinebot

Jira issue originally created by user jneyra:

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.

@doctrinebot

Comment created by jneyra:

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: srvm2m_devicereport
repositoryClass: Iway\M2M\ApiBundle\Entity\DeviceReportRepository

id:
id:
column: reportid
type: integer

generator:
generator:
strategy: SEQUENCE
sequenceGenerator:
sequenceName: srvm2m_device_reportseq
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: srvm2m_reportbattery
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"."SRVM2M_REPORTBATTERY"."REPORTID")

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

@doctrinebot

Comment created by jneyra:

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?

@doctrinebot

Comment created by @asm89:

Please use the mailing list or irc channel for support.

@doctrinebot

Issue was closed with resolution "Invalid"

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment