I am using Cake4. When using the same query, the first entities are linked (as shown in example below). Any changes done to the entity will be reflected on the other.
I was expecting the query to be re-usable and entities created to be separate (new instance). The only way to do this is for me to create a new query.
Can someone point me to the docs which explains this ?
I’m afraid I can’t say. I would have thought that it could, but I haven’t ever needed to do something like this. I’ve turned off buffered results in other scenarios, to keep memory usage down when looping through a large result set, and thought it made sense for this too, but maybe not.
After use, the Query is marked as executed (debug the query to see this). At this point it, seems it will return a buffered result if one exists or null.
I can’t find an easy way to reset the executed state (or to find that property!) although I do believe queries are reusable… just not in this precise way. More on this idea later.
But on the subject of query reuse, I’ve been casually poking into this for a while since listening to video on prepared statements (which I’ve lost track of).
Examining a cake query, you can see the prepared query with placeholders for values. Here is an example:
SELECT
Orders.id AS Orders__id,
Orders.order_number
AS Orders__order_number
FROM orders Orders
WHERE id = :c0
I haven’t figured out how to use these tools. But the clear implication is that queries can be reused and that there is a way to feed simple replacement values to a prepared query object.
It also means that if a Query hasn’t been evaluated, no SQL is ever sent to the database. Once executed, modifying and re-evaluating a query will result in additional SQL being run.
I tested using ResultSet and the results are the same, where both instances returned from query are the same instances (referenced to each-other). The only way to get a totally separate instance is to modify the query (e.g. $query->limit(2)).
$query = $this->Articles->find()->limit(2);
$query->cache(false);
$resultSet = $query->all();
$resultSet->each(function($value,$key) {
$value->title = 'Modified Post';
// debug(spl_object_hash( $value ));
});
// $query->limit(2); // This will create a separate instance
$resultSet2 = $query->all();
$resultSet2->each(function($value,$key) {
// Will show title = 'Modified Post' instead of 'Original Post'
debug( $value->title );
// debug(spl_object_hash( $value ));
});