ENH: Support for @Formula in combination with @ManyToOne

This commit is contained in:
Roland Praml
2016-11-09 16:15:59 +01:00
parent 95ee163d8b
commit e8237cc04f
9 changed files with 110 additions and 13 deletions
@@ -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();
}
}
}
@@ -561,7 +561,9 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
@Override
public void appendSelect(DbSqlContext ctx, boolean subQuery) {
if (!isTransient) {
if (formula) {
ctx.appendFormulaSelect(sqlFormulaSelect);
} else if (!isTransient) {
localHelp.appendSelect(ctx, subQuery);
}
}
@@ -569,6 +571,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
@Override
public void appendFrom(DbSqlContext ctx, SqlJoinType joinType) {
if (!isTransient) {
// TODO JOINS
localHelp.appendFrom(ctx, 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;
}
}
@@ -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) {
@@ -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(pair.getForeignSqlFormula().replace(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(pair.getLocalSqlFormula().replace(tableAliasPlaceHolder, a1));
} else {
sb.append(a1).append(".").append(pair.getLocalDbColumn());
}
}
// add on any inheritance where clause