propelorm/Propel — pull request #876 by ruben-podadera (2014-05-12 13:49:54+00:00)
Title: Versionable Behaviour : bug with multiple identical related objects

Hello,

I think I might found a bug with the versionable behaviour. It happens when a versionable table links twice an other versionable table. I said I might because it could also be that I'm not using the versionable behaviour as I should. In fact I'm having 2 issues, as I will explain.

I have a lease contract, which is signed between two companies, a renter, and a tenant. I'm working within a symfony2 project. I have the following schema :

In one bundle, the company :
```xml

```

In an other bundle, the contract :
```xml

```

This schema results in 4 tables : contract, contract_version, company and company_version.

**First issue**

```php
$tenant_company = new Company();
$tenant_company->setName("TenantCompany");
$tenant_company->save();

$renter_company = new Company();
$renter_company->setName("RenterCompany");
$renter_company->save();

$contract = new Contract();
$contract->setRenterCompany($renter_company);
$contract->setTenantCompany($tenant_company);

$contract->enforceVersioning();
$contract->save();

$contract->toVersion(1);
```
Console :
```
PHP Fatal error: Call to a member function getId() on a non-object in src/Api/UserBundle/Propel/om/BaseCompany.php on line 2478
```

The bug comes from the fact that there is no company version created. I have fixed it by overloading the enforceVersioning method in the Contract.php :

```php
// Contract.php

...
public function enforceVersioning()
{
// used to trigger the modified column status of propel
$this->getRenterCompany()->setUpdatedAt(strtotime("yesterday"))->setUpdatedAt(time())->enforceVersioning();
$this->getTenantCompany()->setUpdatedAt(strtotime("yesterday"))->setUpdatedAt(time())->enforceVersioning();

return parent::enforceVersioning();
}
...
```
Ok, now it works. I assume that I'm doing something wrong in the way I'm doing my work for this point because I have read that the versionable behaviour handles itself the related tables. Obviously I have not found what so I'm doing this bugfix in my code. For the second bug, I really believe there is an issue with the behaviour, that's why I creating this pull request. The purpose og this pull request is not to fix this issue, bug the second one.

**Second issue**

```php
$tenant_company = new Company();
$tenant_company->setName("TenantCompany");
$tenant_company->save();

$renter_company = new Company();
$renter_company->setName("RenterCompany");
$renter_company->save();

$contract = new Contract();
$contract->setRenterCompany($renter_company);
$contract->setTenantCompany($tenant_company);

$contract->enforceVersioning();
$contract->save();

$contract->enforceVersioning();
$contract->save();

$contract->toVersion(2);

echo "Tenant Company : " . $contract->getTenantCompany()->getName() . "\n";
echo "Renter Company : " . $contract->getRenterCompany()->getName() . "\n";
```
Console :
```
Tenant Company : TenantCompany
Renter Company : TenantCompany
```

This is the content of company_version table after the code execution :

| id | renter_company_id | tenant_company_id | version | renter_company_id_version | tenant_company_id_version |
|----|-------------------|-------------------|---------|---------------------------|---------------------------|
| 1 | 2 | 1 | 2 | 2 | 2 |

The bug is in the populateFromVersion of BaseCompany.

The request made to retreive related contract_versions where the company belongs **as the tenant** is made as so :
```sql
SELECT * FROM `contract_version` WHERE (contract_version.id=1 AND contract_version.version=2)
```
So we have one contract.

The request made to retreive related contract_versions where the company belongs **as the renter** is made as so :
```sql
SELECT * FROM `contract_version` WHERE (contract_version.id=1 AND contract_version.version=2)
```
So we have one contract.

Both requests are identical, and they sould not.

With this pull request, here are the requests generated in populateFromVersion :

as a renter :
```sql
SELECT * FROM `contract_version` WHERE (contract_version.id=1 AND contract_version.version=2) AND contract_version.renter_company_id=1
```
as a tenant :
```sql
SELECT * FROM `contract_version` WHERE (contract_version.id=1 AND contract_version.version=2) AND contract_version.tenant_company_id=1
```

So the Company is either found as a tenant company or a renter company, but not for both. The output is now :
```
Tenant Company : TenantCompany
Renter Company : RenterCompany
```