mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge pull request #874 from FOCONIS/feature/inheritance
Feature/inheritance
This commit is contained in:
@@ -85,6 +85,7 @@ import javax.persistence.PersistenceException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -868,7 +869,9 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
|
||||
public void initialiseFkeys() {
|
||||
for (BeanPropertyAssocOne<?> aPropertiesOneImported : propertiesOneImported) {
|
||||
aPropertiesOneImported.addFkey();
|
||||
if (!aPropertiesOneImported.isFormula()) {
|
||||
aPropertiesOneImported.addFkey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -330,7 +330,7 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty {
|
||||
|
||||
if (descriptor.isRawSqlBased()) {
|
||||
String dbColumn = owner.getDbColumn();
|
||||
return new ImportedIdSimple(owner, dbColumn, idProp, 0);
|
||||
return new ImportedIdSimple(owner, dbColumn, null, idProp, 0);
|
||||
}
|
||||
|
||||
TableJoinColumn[] cols = join.columns();
|
||||
@@ -373,16 +373,17 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty {
|
||||
|
||||
String matchColumn = col.getForeignDbColumn();
|
||||
String localColumn = col.getLocalDbColumn();
|
||||
String localSqlFormula = col.getLocalSqlFormula();
|
||||
|
||||
for (int j = 0; j < props.length; j++) {
|
||||
if (props[j].getDbColumn().equalsIgnoreCase(matchColumn)) {
|
||||
return new ImportedIdSimple(owner, localColumn, props[j], j);
|
||||
return new ImportedIdSimple(owner, localColumn, localSqlFormula, props[j], j);
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < others.length; j++) {
|
||||
if (others[j].getDbColumn().equalsIgnoreCase(matchColumn)) {
|
||||
return new ImportedIdSimple(owner, localColumn, others[j], j + props.length);
|
||||
return new ImportedIdSimple(owner, localColumn, localSqlFormula, others[j], j + props.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -570,6 +570,9 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
public void appendFrom(DbSqlContext ctx, SqlJoinType joinType) {
|
||||
if (!isTransient) {
|
||||
localHelp.appendFrom(ctx, joinType);
|
||||
if (sqlFormulaJoin != null) {
|
||||
ctx.appendFormulaJoin(sqlFormulaJoin, joinType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ public class BeanTable {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
public void createJoinColumn(String foreignKeyPrefix, DeployTableJoin join, boolean reverse) {
|
||||
public void createJoinColumn(String foreignKeyPrefix, DeployTableJoin join, boolean reverse, String sqlFormulaSelect) {
|
||||
|
||||
boolean complexKey = false;
|
||||
BeanProperty[] props = idProperties;
|
||||
@@ -104,8 +104,12 @@ public class BeanTable {
|
||||
logger.debug(msg);
|
||||
fk = lc;
|
||||
}
|
||||
if (sqlFormulaSelect != null) {
|
||||
fk = sqlFormulaSelect;
|
||||
}
|
||||
|
||||
DeployTableJoinColumn joinCol = new DeployTableJoinColumn(lc, fk);
|
||||
joinCol.setForeignSqlFormula(sqlFormulaSelect);
|
||||
if (reverse) {
|
||||
joinCol = joinCol.reverse();
|
||||
}
|
||||
|
||||
@@ -13,14 +13,19 @@ public class TableJoinColumn {
|
||||
*/
|
||||
private final String localDbColumn;
|
||||
|
||||
private final String localSqlFormula;
|
||||
|
||||
/**
|
||||
* The foreign database column name.
|
||||
*/
|
||||
private final String foreignDbColumn;
|
||||
|
||||
private final String foreignSqlFormula;
|
||||
|
||||
private final boolean insertable;
|
||||
|
||||
private final boolean updateable;
|
||||
|
||||
|
||||
/**
|
||||
* Hash for including in a query plan
|
||||
@@ -33,6 +38,9 @@ public class TableJoinColumn {
|
||||
public TableJoinColumn(DeployTableJoinColumn deploy) {
|
||||
this.localDbColumn = InternString.intern(deploy.getLocalDbColumn());
|
||||
this.foreignDbColumn = InternString.intern(deploy.getForeignDbColumn());
|
||||
this.localSqlFormula = InternString.intern(deploy.getLocalSqlFormula());
|
||||
this.foreignSqlFormula = InternString.intern(deploy.getForeignSqlFormula());
|
||||
|
||||
this.insertable = deploy.isInsertable();
|
||||
this.updateable = deploy.isUpdateable();
|
||||
this.queryHash = hash();
|
||||
@@ -41,8 +49,11 @@ public class TableJoinColumn {
|
||||
int hash() {
|
||||
int result = localDbColumn != null ? localDbColumn.hashCode() : 0;
|
||||
result = 92821 * result + (foreignDbColumn != null ? foreignDbColumn.hashCode() : 0);
|
||||
result = 92821 * result + (localSqlFormula != null ? localSqlFormula.hashCode() : 0);
|
||||
result = 92821 * result + (foreignSqlFormula != null ? foreignSqlFormula.hashCode() : 0);
|
||||
result = 92821 * result + (insertable ? 1 : 0);
|
||||
result = 92821 * result + (updateable ? 1 : 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -64,7 +75,8 @@ public class TableJoinColumn {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return localDbColumn + " = " + foreignDbColumn;
|
||||
return (localSqlFormula == null ? localDbColumn : localSqlFormula) + " = "
|
||||
+ (foreignSqlFormula == null ? foreignDbColumn : foreignSqlFormula);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,4 +113,13 @@ public class TableJoinColumn {
|
||||
public boolean isUpdateable() {
|
||||
return updateable;
|
||||
}
|
||||
|
||||
public String getLocalSqlFormula() {
|
||||
return localSqlFormula;
|
||||
}
|
||||
|
||||
public String getForeignSqlFormula() {
|
||||
return foreignSqlFormula;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
|
||||
protected final BeanPropertyAssoc<?> owner;
|
||||
|
||||
protected final String localDbColumn;
|
||||
|
||||
protected final String localSqlFormula;
|
||||
|
||||
protected final String logicalName;
|
||||
|
||||
@@ -44,9 +46,10 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
|
||||
|
||||
protected final int position;
|
||||
|
||||
public ImportedIdSimple(BeanPropertyAssoc<?> owner, String localDbColumn, BeanProperty foreignProperty, int position) {
|
||||
public ImportedIdSimple(BeanPropertyAssoc<?> owner, String localDbColumn, String localSqlFormula, BeanProperty foreignProperty, int position) {
|
||||
this.owner = owner;
|
||||
this.localDbColumn = InternString.intern(localDbColumn);
|
||||
this.localSqlFormula = InternString.intern(localSqlFormula);
|
||||
this.foreignProperty = foreignProperty;
|
||||
this.position = position;
|
||||
this.logicalName = InternString.intern(owner.getName() + "." + foreignProperty.getName());
|
||||
@@ -103,7 +106,11 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
|
||||
}
|
||||
|
||||
public void sqlAppend(DbSqlContext ctx) {
|
||||
ctx.appendColumn(localDbColumn);
|
||||
if (localSqlFormula != null) {
|
||||
ctx.appendFormulaSelect(localSqlFormula);
|
||||
} else {
|
||||
ctx.appendColumn(localDbColumn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+9
@@ -96,4 +96,13 @@ public class DeployBeanPropertyAssocOne<T> extends DeployBeanPropertyAssoc<T> {
|
||||
tableJoin.setLocalColumn(dbColumn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSqlFormula(String formulaSelect, String formulaJoin) {
|
||||
super.setSqlFormula(formulaSelect, formulaJoin);
|
||||
DeployTableJoinColumn[] columns = tableJoin.columns();
|
||||
if (columns.length == 1) {
|
||||
columns[0].setLocalSqlFormula(formulaSelect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+55
-5
@@ -15,14 +15,26 @@ public class DeployTableJoinColumn {
|
||||
*/
|
||||
String localDbColumn;
|
||||
|
||||
/**
|
||||
* SQL formula used for local column
|
||||
*/
|
||||
String localSqlFormula;
|
||||
|
||||
/**
|
||||
* The foreign database column name.
|
||||
*/
|
||||
String foreignDbColumn;
|
||||
|
||||
/**
|
||||
* SQL formula used for foreign column
|
||||
*/
|
||||
String foreignSqlFormula;
|
||||
|
||||
final boolean insertable;
|
||||
boolean insertable;
|
||||
|
||||
boolean updateable;
|
||||
|
||||
|
||||
final boolean updateable;
|
||||
|
||||
/**
|
||||
* Construct when automatically determining the join.
|
||||
@@ -43,7 +55,34 @@ public class DeployTableJoinColumn {
|
||||
this.insertable = insertable;
|
||||
this.updateable = updateable;
|
||||
}
|
||||
|
||||
|
||||
public void setLocalSqlFormula(String localSqlFormula) {
|
||||
if (localSqlFormula != null) {
|
||||
this.localSqlFormula = localSqlFormula;
|
||||
this.localDbColumn = null;
|
||||
this.insertable = false;
|
||||
this.updateable = false;
|
||||
}
|
||||
}
|
||||
|
||||
public String getLocalSqlFormula() {
|
||||
return localSqlFormula;
|
||||
}
|
||||
|
||||
public void setForeignSqlFormula(String foreignSqlFormula) {
|
||||
if (foreignSqlFormula != null) {
|
||||
this.foreignSqlFormula = foreignSqlFormula;
|
||||
this.foreignDbColumn = null;
|
||||
this.insertable = false;
|
||||
this.updateable = false;
|
||||
}
|
||||
}
|
||||
|
||||
public String getForeignSqlFormula() {
|
||||
return foreignSqlFormula;
|
||||
}
|
||||
|
||||
|
||||
public DeployTableJoinColumn(boolean order, JoinColumn jc, BeanTable beanTable) {
|
||||
this(jc.referencedColumnName(), jc.name(), jc.insertable(), jc.updatable());
|
||||
setReferencedColumn(beanTable);
|
||||
@@ -68,6 +107,10 @@ public class DeployTableJoinColumn {
|
||||
String temp = localDbColumn;
|
||||
localDbColumn = foreignDbColumn;
|
||||
foreignDbColumn = temp;
|
||||
|
||||
temp = localSqlFormula;
|
||||
localSqlFormula = foreignSqlFormula;
|
||||
foreignSqlFormula = temp;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -86,12 +129,18 @@ public class DeployTableJoinColumn {
|
||||
// Note that the insertable and updateable are just copied
|
||||
// which may not always be the correct thing to do
|
||||
// but will leave it like this for now
|
||||
DeployTableJoinColumn ret;
|
||||
if (reverse){
|
||||
return new DeployTableJoinColumn(foreignDbColumn, localDbColumn, insertable, updateable);
|
||||
ret = new DeployTableJoinColumn(foreignDbColumn, localDbColumn, insertable, updateable);
|
||||
ret.setLocalSqlFormula(foreignSqlFormula);
|
||||
ret.setForeignSqlFormula(localSqlFormula);
|
||||
|
||||
} else {
|
||||
return new DeployTableJoinColumn(localDbColumn, foreignDbColumn, insertable, updateable);
|
||||
ret = new DeployTableJoinColumn(localDbColumn, foreignDbColumn, insertable, updateable);
|
||||
ret.setLocalSqlFormula(localSqlFormula);
|
||||
ret.setForeignSqlFormula(foreignSqlFormula);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@@ -132,4 +181,5 @@ public class DeployTableJoinColumn {
|
||||
public void setLocalDbColumn(String localDbColumn) {
|
||||
this.localDbColumn = localDbColumn;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ public class AnnotationAssocManys extends AnnotationParser {
|
||||
|
||||
// Use the owning bean table to define the join
|
||||
BeanTable owningBeanTable = factory.getBeanTable(descriptor.getBeanType());
|
||||
owningBeanTable.createJoinColumn(fkeyPrefix, prop.getTableJoin(), false);
|
||||
owningBeanTable.createJoinColumn(fkeyPrefix, prop.getTableJoin(), false, prop.getSqlFormulaSelect());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ public class AnnotationAssocOnes extends AnnotationParser {
|
||||
fkeyPrefix = nc.getColumnFromProperty(beanType, prop.getName());
|
||||
}
|
||||
|
||||
beanTable.createJoinColumn(fkeyPrefix, prop.getTableJoin(), true);
|
||||
beanTable.createJoinColumn(fkeyPrefix, prop.getTableJoin(), true, prop.getSqlFormulaSelect());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,11 @@ public class AnnotationFields extends AnnotationParser {
|
||||
}
|
||||
readEmbeddedAttributeOverrides((DeployBeanPropertyAssocOne<?>) prop);
|
||||
}
|
||||
|
||||
Formula formula = get(prop, Formula.class);
|
||||
if (formula != null) {
|
||||
prop.setSqlFormula(formula.select(), formula.join());
|
||||
}
|
||||
}
|
||||
|
||||
private void readField(DeployBeanProperty prop) {
|
||||
|
||||
@@ -152,6 +152,7 @@ public class CQueryPredicates {
|
||||
// this is a find by id type query...
|
||||
request.getBeanDescriptor().bindId(dataBind, idValue);
|
||||
dataBind.append(idValue);
|
||||
dataBind.append(", ");
|
||||
}
|
||||
|
||||
if (bindParams != null) {
|
||||
|
||||
@@ -136,9 +136,20 @@ class DefaultDbSqlContext implements DbSqlContext {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
sb.append(a2).append(".").append(pair.getForeignDbColumn());
|
||||
|
||||
if (pair.getForeignSqlFormula() != null) {
|
||||
sb.append(StringHelper.replaceString(pair.getForeignSqlFormula(), tableAliasPlaceHolder, a2));
|
||||
} else {
|
||||
sb.append(a2).append(".").append(pair.getForeignDbColumn());
|
||||
}
|
||||
|
||||
sb.append(" = ");
|
||||
sb.append(a1).append(".").append(pair.getLocalDbColumn());
|
||||
|
||||
if (pair.getLocalSqlFormula() != null) {
|
||||
sb.append(StringHelper.replaceString(pair.getLocalSqlFormula(), tableAliasPlaceHolder, a1));
|
||||
} else {
|
||||
sb.append(a1).append(".").append(pair.getLocalDbColumn());
|
||||
}
|
||||
}
|
||||
|
||||
// add on any inheritance where clause
|
||||
@@ -244,6 +255,8 @@ class DefaultDbSqlContext implements DbSqlContext {
|
||||
|
||||
sb.append(COMMA);
|
||||
sb.append(converted);
|
||||
|
||||
appendColumnAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user