Bug 88 : missing table alias with embedded key
Priority 
High
Reported Version 
 
Logged By 
imario
Status 
Fixed
Fixed Version 
1.1.0
Assigned To 
 
Product 
Ebean - core
Duplicate Of 
 
Created 
13/03/2009
Updated 
13/03/2009
Type 
Bug
 
Attachments 
No attachments

I have an entity (A) which has an embedded key and a n:1 association (B).
Both entity have some key columns with the same name.

As soon as autoFetch optimizes (it is not an autoFetch problem) the query by making the association eager fetched the column names are no longer unique, and the generated idBindSql in IdBinderEmbedded is missing the table alias - which creates an invalid sql then.

I am not sure if my patch here is a hack, at least it tries to get the dbAlias from "somewhere" in case the deploy itself does not define one, and then, when building the idBindSql one is available to prefix the column.

Index: ../ebean/src/com/avaje/ebean/server/deploy/BeanProperty.java
===================================================================
--- ../ebean/src/com/avaje/ebean/server/deploy/BeanProperty.java (revision 168)
+++ ../ebean/src/com/avaje/ebean/server/deploy/BeanProperty.java Fri Mar 13 10:47:45 CET 2009
@@ -248,7 +247,12 @@

this.dbColumn = deploy.getDbColumn();
this.dbFullName = deploy.getDbFullName();
+ if (deploy.getDbTableAlias() == null) {
+ this.dbTableAlias = descriptor.getBaseTableAlias();
+ }
+ else {
- this.dbTableAlias = deploy.getDbTableAlias();
+ this.dbTableAlias = deploy.getDbTableAlias();
+ }
this.sqlFormulaJoin = deploy.getSqlFormulaJoin();
this.sqlFormulaSelect = deploy.getSqlFormulaSelect();
this.formula = sqlFormulaSelect != null;
Index: ../ebean/src/com/avaje/ebean/server/deploy/id/IdBinderEmbedded.java
===================================================================
--- ../ebean/src/com/avaje/ebean/server/deploy/id/IdBinderEmbedded.java (revision 168)
+++ ../ebean/src/com/avaje/ebean/server/deploy/id/IdBinderEmbedded.java Fri Mar 13 10:40:01 CET 2009
@@ -133,6 +133,9 @@
if (i > 0) {
sb.append(" AND ");
}
+
+ sb.append(embIdProperty.getDbTableAlias());
+ sb.append(".");
sb.append(props[i].getDbFullName());
sb.append(" = ? ");
}

 
Rob 13 Mar 10:49
Reproduced

I think I have reproduced the problem.

T0DetailId id = new T0DetailId(3,4);

T0Detail detail
= Ebean.find(T0Detail.class)
.join("master").setId(id).findUnique();

generates sql with no table alias on the embedded id columns... and you get a sql error "Ambiguous column name d1_id ..."

where d1_id = ? AND d2_id = ?

Rob 13 Mar 11:02
The full sql was...


select d.d1_id, d.d2_id, d.detail
, m.d1_id, m.name
from t0_detail d
left outer join t0_master m on d.m_id = m.d1_id
where d1Id = ? AND d2Id = ?

Rob 13 Mar 11:12
I follow ...

Yes, I understand your fix. I'm pretty happy that it is not a hack... in that the table alias is not set on Embedded beans, so the IF check in BeanProperty is detecting that case... and getting the 'base table alias'.

I'll ponder a bit more but it looks good to me.

Thanks, Rob.

imario 13 Mar 11:35
additional thoughts about the fix

The thing which makes me not that happy is in IdBinderEmbedded.java where I add the table alias, but the javadoc states that getDbFullName() already delivers the full name - with alias.

The other solution I had in mind was to make dbTableAlias non-final and set it in the "second pass" once the table knows its alias.

Rob 15 Mar 02:13
Yes - a better fix

Yes, I think a better fix is (in BeanPropertyAssocOne) to use:

BeanEmbeddedMeta overrideMeta = BeanEmbeddedMetaFactory.create(owner, deploy, descriptor);
embeddedProps = overrideMeta.getProperties();


... it was being used for Embedded beans but not EmbeddedId beans... so I have made the change that it is used for ALL Embedded beans (aka also used for EmbeddedId).

What the BeanEmbeddedMetaFactory does is effectly set the table alias on the properties (returning them via overrideMeta.getProperties();)

That means the getDbFullName() is correct again.

I'm committing up this fix into HEAD along with some other changes (improved error messages and conditionally using the column alias on imported concatinated keys).

Fixed in HEAD.

woResponse

Upload a file