Bug: Wrong join in query with @Inheritance and @DbForeignKey

This commit is contained in:
Noemi Szemenyei committed 2022-03-15 15:37:43 +01:00
1 parent 256f000dec
commit f274743736
14 files changed
+291 -10

No files matched your search

@@ -3,6 +3,7 @@ package io.ebeaninternal.server.deploy;
import io.ebean.bean.EntityBean;
import io.ebean.bean.PersistenceContext;
import io.ebeaninternal.server.query.SqlJoinType;
import io.ebeaninternal.server.query.SqlTreeJoin;
import java.sql.SQLException;
@@ -60,11 +61,28 @@ final class AssocOneHelpRefInherit extends AssocOneHelp {
return ref;
}
@Override
void appendFrom(DbSqlContext ctx, SqlJoinType joinType) {
// add join to support the discriminator column
String relativePrefix = ctx.getRelativePrefix(property.name);
property.tableJoin.addJoin(joinType, relativePrefix, ctx);
ctx.addExtraJoin(new Extra(relativePrefix, joinType));
}
/**
* Extra join to support the discriminator column.
*/
final class Extra implements SqlTreeJoin {
final String relativePrefix;
final SqlJoinType joinType;
Extra(String relativePrefix, SqlJoinType joinType) {
this.relativePrefix = relativePrefix;
this.joinType = joinType;
}
@Override
public void addJoin(DbSqlContext ctx) {
// add join to support the discriminator column *IF* join is not already present
property.tableJoin.addJoin(joinType, relativePrefix, ctx);
}
}
/**
@@ -1,6 +1,7 @@
package io.ebeaninternal.server.deploy;
import io.ebeaninternal.server.query.SqlJoinType;
import io.ebeaninternal.server.query.SqlTreeJoin;
/**
* Used to provide context during sql construction.
@@ -133,4 +134,13 @@ public interface DbSqlContext {
*/
void appendFromForUpdate();
/**
* Delay adding an extra join to support inheritance discriminator in projection (IF required).
*/
void addExtraJoin(SqlTreeJoin treeJoin);
/**
* Add extra joins *IF* required to support inheritance discriminator in projection.
*/
void flushExtraJoins();
}
@@ -7,6 +7,7 @@ import io.ebeaninternal.server.util.ArrayStack;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
final class DefaultDbSqlContext implements DbSqlContext {
@@ -43,7 +44,9 @@ final class DefaultDbSqlContext implements DbSqlContext {
private String currentPrefix;
private ArrayList<BeanProperty> encryptedProps;
private List<BeanProperty> encryptedProps;
private List<SqlTreeJoin> extraJoins;
private final CQueryDraftSupport draftSupport;
@@ -70,6 +73,24 @@ final class DefaultDbSqlContext implements DbSqlContext {
return alias.isIncludeSoftDelete();
}
@Override
public void addExtraJoin(SqlTreeJoin treeJoin) {
if (extraJoins == null) {
extraJoins = new ArrayList<>();
}
extraJoins.add(treeJoin);
}
@Override
public void flushExtraJoins() {
if (extraJoins != null) {
for (SqlTreeJoin extra : extraJoins) {
extra.addJoin(this);
}
extraJoins = null;
}
}
@Override
public void appendFromForUpdate() {
if (fromForUpdate != null) {
@@ -256,7 +256,7 @@ public final class SqlTreeBuilder {
}
addManyWhereJoins(myJoinList);
}
extraProps.forEach(props::add);
extraProps.forEach(props::add); //addExtra
if (!rawSql && manyWhereJoins.isFormulaWithJoin(prefix)) {
for (String property : manyWhereJoins.getFormulaJoinProperties(prefix)) {
@@ -0,0 +1,15 @@
package io.ebeaninternal.server.query;
import io.ebeaninternal.server.deploy.DbSqlContext;
/**
* Extra Sql joins conditionally added if required (after children are joined).
*/
public interface SqlTreeJoin {
/**
* Add the extra join if required.
*/
void addJoin(DbSqlContext ctx);
}
@@ -279,18 +279,16 @@ class SqlTreeNodeBean implements SqlTreeNode {
ctx.pushTableAlias(prefix);
baseTableAlias = ctx.getTableAlias(prefix);
// join and return SqlJoinType to use for child joins
joinType = appendFromBaseTable(ctx, joinType);
for (STreeProperty property : properties) {
// usually nothing... except for 1-1 Exported
property.appendFrom(ctx, joinType, null);
}
for (SqlTreeNode child : children) {
child.appendFrom(ctx, joinType);
}
ctx.flushExtraJoins();
ctx.popTableAlias();
ctx.popJoin();
}