A few questions..

5 views
Skip to first unread message

Fabio

unread,
Oct 20, 2008, 9:33:02 PM10/20/08
to Outlet ORM
Hy Alvaro,

I ran into an issue today and I'd like to know how you think would be
the best way to solve it. I'll use the classic Order and OrderLine
model to explain it.

Supose the user creates an Order with a few OrderLines and then decide
to update it, adding, removing and keeping some OrderLines. My
question is, using Outlet what would you think would be the best way
to make it work?
This is what I will do until you can reply this message:

$order = $this->orderRepository->Load($id);
$this->orderRepository->ClearOrderLines($order);

foreach...... {
$orderLine = new OrderLine();
$orderLine->setOrder($order);
...
$order->addOrderLine($orderLine);
}

$this->orderRepository->Save($order);


What do you think? Is there a better way to achieve it? (I'm doing
what I'm used to do without an ORM that is removing related entities
and inserting everything again)
I've got a unit of work injected inside the repository so everything
is inside the same transaction. I actually had to change the library
code to achieve it and thats why I am sending this message, I believe
you probably have something else in mind.

Thanks for your atenttion.
--
Fabio

Fabio

unread,
Oct 20, 2008, 10:00:07 PM10/20/08
to Outlet ORM
I forgot to mention the other questions...

Do you have something in mind to handle an entity with composite
primary key? I created another column with a simple autoincrement key
so workaround this.

The other question is about the identity map.
I had a look at your 'select' method and found out that you are
inserting the entity in the identity map after creating it. I think
that an entity that was already loaded shouldn't be created, its
values shouldn't be gotten taken from identity map?
This is the code I'm talking about:

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$obj = new $proxyclass();
$this->populateObject($clazz, $obj, $row);
$collection[] = $obj;
}

Shouldn't it be something like:
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$pk = {some way to get the primary key for the current row};
if (isset($this->identity_map[$clazz][$pk]))
$collection[] = $this->identity_map[$clazz][$pk];
else {
$obj = new $proxyclass();
$this->populateObject($clazz, $obj, $row);
$collection[] = $obj;
$this->identity_map[$clazz][$pk] = $obj;
}
}


Keep up with the good work :-)

Alvaro Carrasco

unread,
Oct 20, 2008, 10:04:51 PM10/20/08
to outle...@googlegroups.com
Hi Fabio,

Looking at your code, I don't think I would have done things any
differently. If I need better performance I might look a little closer
to see if I can avoid re-adding OrderLines that already existed. Even
then I would probably still use the repository to do that, since I don't
think there's any way the ORM can take care of it for you.

What modifications were necessary to achieve this? Are you talking about
the unit-of-work?

Thanks,
Alvaro

Fabio

unread,
Oct 21, 2008, 11:25:19 PM10/21/08
to Outlet ORM
My bad, I mixed everything up....

One of the things you already answered, the other 2 are the things I
mentioned in the last message about the composite key and the identity
map.

What I've chaged in the library was one thing that I don't know if it
is classified as a bug but here we go:

OutletMapper.php
private function saveOneToMany () {
$conf = Outlet::getInstance()->getConfig()->getEntity($this->cls);

$return = true; // this line

foreach ($conf->getAssociations() as $assoc) {
if ($assoc->getType() != 'one-to-many') continue;

$key = $assoc->getKey();
$getter = $assoc->getGetter();
$setter = $assoc->getSetter();

$children = $this->obj->$getter(null);
if (sizeof($children) == 0) continue; // I added this line because
foreach ($children as &$child) {
$child->$key = $this->getPK();

$mapped = new self($child);
if ($mapped->isNew()) {

$return = $mapped->save() && $return; // this line

}
}

$this->obj->$setter( $children );
}


return $return; // this line
}

I also had to add a 'return $this->saveOneToMany()' on the last line
of insert().

I don't know if I did the right way but what I think is that the
save() method is not returning true when everything works fine, I
think I solved the insert() method but the update() is looking the
same since there is no 'return'.

I'm using the files on /trunk
See ya,
Fabio

Alvaro Carrasco

unread,
Oct 22, 2008, 1:31:20 AM10/22/08
to outle...@googlegroups.com
Hmm... I see what you are saying. I think you're right, it should return
the object from the identity map. I'll see if I can change it to do that.

Thanks,
Alvaro

Alvaro Carrasco

unread,
Oct 22, 2008, 1:43:52 AM10/22/08
to outle...@googlegroups.com
Sorry, I'm switching to bottom posting, see below.


Fabio wrote:
> My bad, I mixed everything up....
>
> One of the things you already answered, the other 2 are the things I
> mentioned in the last message about the composite key and the identity
> map.
>
> What I've chaged in the library was one thing that I don't know if it
> is classified as a bug but here we go:
>
> OutletMapper.php
> private function saveOneToMany () {
> $conf = Outlet::getInstance()->getConfig()->getEntity($this->cls);
>
> $return = true; // this line
>
> foreach ($conf->getAssociations() as $assoc) {
> if ($assoc->getType() != 'one-to-many') continue;
>
> $key = $assoc->getKey();
> $getter = $assoc->getGetter();
> $setter = $assoc->getSetter();
>
> $children = $this->obj->$getter(null);
> if (sizeof($children) == 0) continue; // I added this line because

I'm not sure why the line above was added. What would happen if there's
more than one 'one-to-many' association?

> foreach ($children as &$child) {
> $child->$key = $this->getPK();
>
> $mapped = new self($child);
> if ($mapped->isNew()) {
>
> $return = $mapped->save() && $return; // this line
>
> }
> }
>
> $this->obj->$setter( $children );
> }
>
>
> return $return; // this line

Was returning a boolean here necessary for your implementation of
unit-of-work? Assuming database errors throw exceptions, when would you
expect false?

> }
>
> I also had to add a 'return $this->saveOneToMany()' on the last line
> of insert().
>
> I don't know if I did the right way but what I think is that the
> save() method is not returning true when everything works fine, I
> think I solved the insert() method but the update() is looking the
> same since there is no 'return'.
>
> I'm using the files on /trunk
> See ya,
> Fabio
>


Thanks for your feedback and good catch on the identity map stuff.

Alvaro

Fabio

unread,
Oct 22, 2008, 7:38:04 AM10/22/08
to Outlet ORM
> I'm not sure why the line above was added. What would happen if there's
> more than one 'one-to-many' association?

My bad again :P
Found out that the problem was that my getXXX wasn't returning an
array.


> Was returning a boolean here necessary for your implementation of
> unit-of-work? Assuming database errors throw exceptions, when would you
> expect false?
>

Looking that way I think you are right. I'm still getting used to
exceptions in PHP since I spent a lot of time developing with PHP 4.

What about the composite keys?


Thanks for your reply and looking forward for the identity map change.
Just let me know I'm being annoying. hehe :P
--
Fabio
Reply all
Reply to author
Forward
0 new messages