fix!: EXPOSED-851 Not use Cached Entity when reference column defined with .references()#2614
fix!: EXPOSED-851 Not use Cached Entity when reference column defined with .references()#2614obabichevjb wants to merge 1 commit into
.references()#2614Conversation
… with `.references()`
| ## 1.0.0-rc-2 | ||
|
|
||
| * The method `references()` with `EntityID` ref parameter changed the signature from | ||
| `fun <T : Any, S : T, C : Column<S>> C.references(ref: Column<EntityID<T>>, ...): C` to | ||
| `fun <T : Any, C : Column<T>> C.references(ref: Column<EntityID<T>>, ...): Column<EntityID<T>>`. It's done to align signature and behaviour of `references()` method | ||
| with `reference()` method. | ||
|
|
There was a problem hiding this comment.
From my understanding, the current setup is intentional. reference() and Column.references() are not meant to be 100% equivalent or to be aligned exactly.
Column.references() exists for users that want to keep the column they have defined/registered, but only additionally create a foreign key on table DDL.
There could be DSL users who are choosing to use IntIdTable for convenience but don't want to deal with EntityID any more than necessary and who purposefully want to strip the entityID wrapper from the referenced column.
I think there could be a lot of people who want the original distinction to remain:
// registers a new integer column + create FK
val city: Column<Int> = integer("city_id").references(Cities.id)
// registers an entityID column that matches reference + create FK
val city: Column<EntityID<Int>> = reference("city_id", Cities.id)My question is:
If the user is relying on DAO, and therefore expects the cache to be utilised to minimise db queries, why are they using .references() instead of reference()?
If there is no reason, maybe we should be making it clear in documentation that .references() does not involve the entity cache?
There was a problem hiding this comment.
@bog-walk Thank you, it makes sense,
in this case it could be better update documentation,
but in this case I see the problem that Exposed allows to create reference for entity on such a column, and allows to fetch entities using with(), but makes extra queries in this case, and there is no way for the user that it would happen without checking the logs, and it's easy to mix reference() and references() within code.
I will check, probably it could be easy to prevent usage of referrersOn() on columns that have no EntityID<T> in type.
There was a problem hiding this comment.
Firstly, thank you for taking care of this issue as an issue reporter.
I didn't expect the references() method to affect the cache behaviour either and had to look at the code to analyse the cause. As mentioned above, If the references() method is not intended to wrap EntityID, It would be helpful to have clear documentation stating that cached entities will not be used for reference columns with references().
However, as @obabichevjb said, even with documentation, the behavior of references() appears fine on the surface, and the issue is only apparent in the logs. Therefore, I think it's better to be more defensive to prevent user mistakes.
Description
The root problem from the issue
EXPOSED-851is that callEntity.find().with()performs more sql queries than it should.if the columnd with reference defined as
val alertItemId = integer("alert_item_id").references(AlertItemTable.id, ...)some extra queries on the parent entity is performed, but if it's defined viaval alertItemId = reference(...)it doesn't happen.For that case the signatures of these methods have the following structure:
In the case of
reference()the method is defined forColumn<EntityID<T>>reference and returnsColumn<E> ~ Column<EntitytID<T>>column.From other side the method
references()is also defined onColumn<EntityID<T>>reference, but returnsColumn<Scolumn (withoutEntityID). Internally that method also doesn't register the current column as entity id column.The solution is to align behavior of
references()method to thereference()method.Type of Change
Please mark the relevant options with an "X":
Updates/remove existing public API methods:
Affected databases:
Related Issues
EXPOSED-851 Not use Cached Entity when reference column defined with
.references()