mirror of https://github.com/apache/openjpa.git
OPENJPA-1253: refactoring the checking of non-default mapping to AbstractFieldStrategy
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@819822 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7d6ccb108c
commit
c8d1003612
|
@ -20,10 +20,14 @@ package org.apache.openjpa.jdbc.meta.strats;
|
|||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
|
||||
import org.apache.openjpa.jdbc.kernel.JDBCStore;
|
||||
import org.apache.openjpa.jdbc.meta.ClassMapping;
|
||||
import org.apache.openjpa.jdbc.meta.FieldMapping;
|
||||
import org.apache.openjpa.jdbc.meta.FieldMappingInfo;
|
||||
import org.apache.openjpa.jdbc.meta.FieldStrategy;
|
||||
import org.apache.openjpa.jdbc.schema.ForeignKey;
|
||||
import org.apache.openjpa.jdbc.sql.Joins;
|
||||
import org.apache.openjpa.jdbc.sql.Result;
|
||||
import org.apache.openjpa.jdbc.sql.RowManager;
|
||||
|
@ -32,6 +36,8 @@ import org.apache.openjpa.jdbc.sql.Select;
|
|||
import org.apache.openjpa.jdbc.sql.SelectExecutor;
|
||||
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||
import org.apache.openjpa.lib.util.Localizer;
|
||||
import org.apache.openjpa.meta.FieldMetaData;
|
||||
import org.apache.openjpa.meta.JavaTypes;
|
||||
import org.apache.openjpa.util.MetaDataException;
|
||||
|
||||
/**
|
||||
|
@ -46,6 +52,13 @@ public abstract class AbstractFieldStrategy
|
|||
private static final Localizer _loc = Localizer.forPackage
|
||||
(AbstractFieldStrategy.class);
|
||||
|
||||
private Boolean _isNonDefaultMappingAllowed = null;
|
||||
private Boolean _isBi1ToMJT = null;
|
||||
private Boolean _isUni1ToMFK = null;
|
||||
private Integer _bi1ToMJT = null; //index of the field
|
||||
private ForeignKey _bi_1ToM_JoinFK = null;
|
||||
private ForeignKey _bi_1ToM_ElemFK = null;
|
||||
|
||||
/**
|
||||
* The owning field mapping.
|
||||
*/
|
||||
|
@ -181,4 +194,107 @@ public abstract class AbstractFieldStrategy
|
|||
Object prevValue)
|
||||
throws SQLException {
|
||||
}
|
||||
|
||||
private void isNonDefaultMapping() {
|
||||
FieldMapping mapped = field.getMappedByMapping();
|
||||
_isBi1ToMJT = false;
|
||||
_isUni1ToMFK = false;
|
||||
if (isNonDefaultMappingAllowed()) {
|
||||
if (field.getAssociationType() == FieldMetaData.ONE_TO_MANY ) {
|
||||
if (mapped == null) {
|
||||
if (hasJoinTable())
|
||||
return;
|
||||
else if (hasJoinColumn()) {
|
||||
_isUni1ToMFK = true;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (hasJoinTable()) {
|
||||
_isBi1ToMJT = true;
|
||||
return;
|
||||
} else if (hasJoinColumn()){
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasJoinColumn() {
|
||||
boolean hasJoinColumn = (field.getValueInfo().getColumns().size() > 0 ? true : false);
|
||||
return hasJoinColumn;
|
||||
}
|
||||
|
||||
private boolean hasJoinTable() {
|
||||
boolean hasJoinTable = (field.getMappingInfo().getTableName() != null ? true : false);
|
||||
return hasJoinTable;
|
||||
}
|
||||
|
||||
public boolean isBi1ToMJT() {
|
||||
if (_isBi1ToMJT == null)
|
||||
isNonDefaultMapping();
|
||||
return _isBi1ToMJT;
|
||||
}
|
||||
|
||||
public boolean isUni1ToMFK() {
|
||||
if (_isUni1ToMFK == null)
|
||||
isNonDefaultMapping();
|
||||
return _isUni1ToMFK;
|
||||
}
|
||||
|
||||
protected boolean isNonDefaultMappingAllowed() {
|
||||
if (_isNonDefaultMappingAllowed == null) {
|
||||
OpenJPAConfiguration conf = field.getRepository().getConfiguration();
|
||||
_isNonDefaultMappingAllowed = field.getRepository().
|
||||
getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf);
|
||||
}
|
||||
return _isNonDefaultMappingAllowed;
|
||||
}
|
||||
|
||||
protected void getBiOneToManyInfo() {
|
||||
_bi1ToMJT = -1;
|
||||
if (!isNonDefaultMappingAllowed())
|
||||
return;
|
||||
ClassMapping inverse = field.getValueMapping().getTypeMapping();
|
||||
FieldMapping[] fmds = inverse.getFieldMappings();
|
||||
for (int i = 0; i < fmds.length; i++) {
|
||||
if (field == fmds[i].getMappedByMapping()) {
|
||||
int typeCode = fmds[i].getDeclaredTypeCode();
|
||||
if (typeCode == JavaTypes.ARRAY ||
|
||||
typeCode == JavaTypes.COLLECTION ||
|
||||
typeCode == JavaTypes.MAP) {
|
||||
// this is a bi-directional oneToMany relation with
|
||||
// @JoinTable annotation ==> join table strategy
|
||||
// ==> should not mapped in the owner's table
|
||||
FieldMappingInfo info = fmds[i].getMappingInfo();
|
||||
if (info.getTableName() != null)
|
||||
_bi1ToMJT = i;
|
||||
_bi_1ToM_ElemFK = fmds[i].getElementMapping().getForeignKey();
|
||||
_bi_1ToM_JoinFK = fmds[i].getJoinForeignKey();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int getFieldIndexBi1ToMJT() {
|
||||
if (_bi1ToMJT == null) {
|
||||
getBiOneToManyInfo();
|
||||
}
|
||||
return _bi1ToMJT;
|
||||
}
|
||||
|
||||
protected ForeignKey getBi1ToMElemFK() {
|
||||
if (_bi1ToMJT == null) {
|
||||
getBiOneToManyInfo();
|
||||
}
|
||||
return _bi_1ToM_ElemFK;
|
||||
}
|
||||
|
||||
protected ForeignKey getBi1ToMJoinFK() {
|
||||
if (_bi1ToMJT == null) {
|
||||
getBiOneToManyInfo();
|
||||
}
|
||||
return _bi_1ToM_JoinFK;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,51 +66,10 @@ public abstract class MapTableFieldStrategy
|
|||
private static final Localizer _loc = Localizer.forPackage
|
||||
(MapTableFieldStrategy.class);
|
||||
|
||||
private Boolean _isNonDefaultMappingAllowed = null;
|
||||
private Boolean _isBi1ToMJT = null;
|
||||
private Boolean _isUni1ToMFK = null;
|
||||
|
||||
public FieldMapping getFieldMapping() {
|
||||
return field;
|
||||
}
|
||||
|
||||
private void isNonDefaultMapping() {
|
||||
FieldMapping mapped = field.getMappedByMapping();
|
||||
if (isNonDefaultMappingAllowed() &&
|
||||
field.getAssociationType() == FieldMetaData.ONE_TO_MANY &&
|
||||
hasJoinColumnOrJoinTable()) {
|
||||
if (mapped != null) {
|
||||
_isBi1ToMJT = true;
|
||||
_isUni1ToMFK = false;
|
||||
} else {
|
||||
_isBi1ToMJT = false;
|
||||
_isUni1ToMFK = true;
|
||||
}
|
||||
} else {
|
||||
_isBi1ToMJT = false;
|
||||
_isUni1ToMFK = false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasJoinColumnOrJoinTable() {
|
||||
boolean hasJoinColumn = (field.getValueInfo().getColumns().size() > 0 ? true : false);
|
||||
boolean hasJoinTable = (field.getMappingInfo().getTableName() != null ? true : false);
|
||||
return hasJoinColumn || hasJoinTable;
|
||||
|
||||
}
|
||||
|
||||
public boolean isBi1ToMJT() {
|
||||
if (_isBi1ToMJT == null)
|
||||
isNonDefaultMapping();
|
||||
return _isBi1ToMJT;
|
||||
}
|
||||
|
||||
public boolean isUni1ToMFK() {
|
||||
if (_isUni1ToMFK == null)
|
||||
isNonDefaultMapping();
|
||||
return _isUni1ToMFK;
|
||||
}
|
||||
|
||||
public ClassMapping[] getIndependentKeyMappings(boolean traverse) {
|
||||
return (traverse) ? field.getKeyMapping().getIndependentTypeMappings()
|
||||
: ClassMapping.EMPTY_MAPPINGS;
|
||||
|
@ -161,15 +120,6 @@ public abstract class MapTableFieldStrategy
|
|||
field.getValueInfo().assertNoSchemaComponents(field, !adapt);
|
||||
}
|
||||
|
||||
protected boolean isNonDefaultMappingAllowed() {
|
||||
if (_isNonDefaultMappingAllowed == null) {
|
||||
OpenJPAConfiguration conf = field.getRepository().getConfiguration();
|
||||
_isNonDefaultMappingAllowed = field.getRepository().
|
||||
getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf);
|
||||
}
|
||||
return _isNonDefaultMappingAllowed;
|
||||
}
|
||||
|
||||
public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
|
||||
throws SQLException {
|
||||
Row row = rm.getAllRows(field.getTable(), Row.ACTION_DELETE);
|
||||
|
|
|
@ -83,9 +83,6 @@ public class RelationFieldStrategy
|
|||
(RelationFieldStrategy.class);
|
||||
|
||||
private Boolean _fkOid = null;
|
||||
private int _biOneToManyJoinTable = -1;
|
||||
private ForeignKey _biOneToManyJoinFK = null;
|
||||
private ForeignKey _biOneToManyElemFK = null;
|
||||
|
||||
public void map(boolean adapt) {
|
||||
if (field.getTypeCode() != JavaTypes.PC || field.isEmbeddedPC())
|
||||
|
@ -139,11 +136,7 @@ public class RelationFieldStrategy
|
|||
field.setUseClassCriteria(criteria);
|
||||
return;
|
||||
} else { // this could be the owner in a bi-directional relation
|
||||
OpenJPAConfiguration conf = field.getRepository().getConfiguration();
|
||||
boolean isNonDefaultMappingAllowed = field.getRepository().
|
||||
getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf);
|
||||
if (isNonDefaultMappingAllowed)
|
||||
getBiOneToManyInfo();
|
||||
getBiOneToManyInfo();
|
||||
}
|
||||
|
||||
// this is necessary to support openjpa 3 mappings, which didn't
|
||||
|
@ -168,7 +161,7 @@ public class RelationFieldStrategy
|
|||
if (field.getMappedByIdValue() != null)
|
||||
setMappedByIdColumns();
|
||||
|
||||
if (_biOneToManyJoinTable == -1) {
|
||||
if (getFieldIndexBi1ToMJT() == -1) {
|
||||
ForeignKey fk = vinfo.getTypeJoin(field, field.getName(), true,
|
||||
adapt);
|
||||
field.setForeignKey(fk);
|
||||
|
@ -279,7 +272,7 @@ public class RelationFieldStrategy
|
|||
updateInverse(sm, rel, store, rm);
|
||||
else {
|
||||
Row row = field.getRow(sm, store, rm, Row.ACTION_INSERT);
|
||||
if (row != null && _biOneToManyJoinTable == -1) {
|
||||
if (row != null && getFieldIndexBi1ToMJT() == -1) {
|
||||
field.setForeignKey(row, rel);
|
||||
// this is for bi-directional maps, the key and value of the
|
||||
// map are stored in the table of the mapped-by entity
|
||||
|
@ -346,6 +339,12 @@ public class RelationFieldStrategy
|
|||
if (mapObj.get(key) == value)
|
||||
return key;
|
||||
}
|
||||
Set<Map.Entry> entries = mapObj.entrySet();
|
||||
for (Map.Entry entry : entries) {
|
||||
if (entry.getValue() == value)
|
||||
return entry.getKey();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -365,29 +364,25 @@ public class RelationFieldStrategy
|
|||
field.isBidirectionalJoinTableMappingNonOwner()) ?
|
||||
Row.ACTION_DELETE : Row.ACTION_UPDATE;
|
||||
Row row = field.getRow(sm, store, rm, action);
|
||||
if (row != null && _biOneToManyJoinTable == -1) {
|
||||
if (row != null && getFieldIndexBi1ToMJT() == -1) {
|
||||
field.setForeignKey(row, rel);
|
||||
// this is for bi-directional maps, the key and value of the
|
||||
// map are stored in the table of the mapped-by entity
|
||||
setMapKey(sm, rel, store, row);
|
||||
}
|
||||
|
||||
if (_biOneToManyJoinTable != -1) { // also need to update the join table
|
||||
PersistenceCapable invPC = (PersistenceCapable)sm.fetchObject(_biOneToManyJoinTable);
|
||||
if (getFieldIndexBi1ToMJT() != -1) { // also need to update the join table
|
||||
PersistenceCapable invPC = (PersistenceCapable)sm.fetchObject(getFieldIndexBi1ToMJT());
|
||||
Row secondaryRow = null;
|
||||
if (invPC != null) {
|
||||
secondaryRow = rm.getSecondaryRow(_biOneToManyJoinFK.getTable(),
|
||||
secondaryRow = rm.getSecondaryRow(getBi1ToMJoinFK().getTable(),
|
||||
Row.ACTION_INSERT);
|
||||
secondaryRow.setForeignKey(_biOneToManyElemFK, null, sm);
|
||||
secondaryRow.setForeignKey(_biOneToManyJoinFK, null,
|
||||
secondaryRow.setForeignKey(getBi1ToMElemFK(), null, sm);
|
||||
secondaryRow.setForeignKey(getBi1ToMJoinFK(), null,
|
||||
RelationStrategies.getStateManager(invPC,
|
||||
store.getContext()));
|
||||
} else {
|
||||
secondaryRow = rm.getSecondaryRow(_biOneToManyJoinFK.getTable(),
|
||||
Row.ACTION_DELETE);
|
||||
secondaryRow.setForeignKey(_biOneToManyElemFK, null, sm);
|
||||
rm.flushSecondaryRow(secondaryRow);
|
||||
}
|
||||
rm.flushSecondaryRow(secondaryRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -561,7 +556,7 @@ public class RelationFieldStrategy
|
|||
*/
|
||||
private void selectEagerParallel(Select sel, ClassMapping cls,
|
||||
JDBCStore store, JDBCFetchConfiguration fetch, int eagerMode) {
|
||||
if (_biOneToManyJoinTable != -1)
|
||||
if (getFieldIndexBi1ToMJT() != -1)
|
||||
return;
|
||||
sel.selectPrimaryKey(field.getDefiningMapping());
|
||||
// set a variable name that does not conflict with any in the query;
|
||||
|
@ -576,7 +571,7 @@ public class RelationFieldStrategy
|
|||
|
||||
public void selectEagerJoin(Select sel, OpenJPAStateManager sm,
|
||||
JDBCStore store, JDBCFetchConfiguration fetch, int eagerMode) {
|
||||
if (_biOneToManyJoinTable != -1)
|
||||
if (getFieldIndexBi1ToMJT() != -1)
|
||||
return;
|
||||
|
||||
// limit the eager mode to single on recursive eager fetching b/c
|
||||
|
@ -681,7 +676,7 @@ public class RelationFieldStrategy
|
|||
public void loadEagerJoin(OpenJPAStateManager sm, JDBCStore store,
|
||||
JDBCFetchConfiguration fetch, Result res)
|
||||
throws SQLException {
|
||||
if (_biOneToManyJoinTable != -1)
|
||||
if (getFieldIndexBi1ToMJT() != -1)
|
||||
return;
|
||||
ClassMapping cls = field.getIndependentTypeMappings()[0];
|
||||
|
||||
|
@ -730,7 +725,7 @@ public class RelationFieldStrategy
|
|||
// get the related object's oid
|
||||
ClassMapping relMapping = field.getTypeMapping();
|
||||
Object oid = null;
|
||||
if (relMapping.isMapped() && _biOneToManyJoinTable == -1) {
|
||||
if (relMapping.isMapped() && getFieldIndexBi1ToMJT() == -1) {
|
||||
oid = relMapping.getObjectId(store, res, field.getForeignKey(),
|
||||
field.getPolymorphic() != ValueMapping.POLY_FALSE, null);
|
||||
} else {
|
||||
|
@ -796,16 +791,16 @@ public class RelationFieldStrategy
|
|||
sel.whereForeignKey(field.getForeignKey(rels[idx]),
|
||||
sm.getObjectId(), field.getDefiningMapping(), store);
|
||||
else {
|
||||
if (_biOneToManyJoinTable == -1) {
|
||||
if (getFieldIndexBi1ToMJT() == -1) {
|
||||
resJoins[idx] = sel.newJoins().joinRelation(field.getName(),
|
||||
field.getForeignKey(rels[idx]), rels[idx],
|
||||
field.getSelectSubclasses(), false, false);
|
||||
field.wherePrimaryKey(sel, sm, store);
|
||||
} else {
|
||||
resJoins[idx] = sel.newJoins().joinRelation(null,
|
||||
getBiOneToManyJoinFK(), rels[idx],
|
||||
getBi1ToMJoinFK(), rels[idx],
|
||||
field.getSelectSubclasses(), false, false);
|
||||
sel.whereForeignKey(getBiOneToManyElemFK(), sm.getObjectId(),
|
||||
sel.whereForeignKey(getBi1ToMElemFK(), sm.getObjectId(),
|
||||
field.getDefiningMapping(), store);
|
||||
}
|
||||
}
|
||||
|
@ -826,43 +821,6 @@ public class RelationFieldStrategy
|
|||
}
|
||||
}
|
||||
|
||||
private ForeignKey getBiOneToManyJoinFK() {
|
||||
if (_biOneToManyJoinFK == null) {
|
||||
getBiOneToManyInfo();
|
||||
}
|
||||
return _biOneToManyJoinFK;
|
||||
}
|
||||
|
||||
private ForeignKey getBiOneToManyElemFK() {
|
||||
if (_biOneToManyElemFK == null) {
|
||||
getBiOneToManyInfo();
|
||||
}
|
||||
return _biOneToManyElemFK;
|
||||
}
|
||||
|
||||
private void getBiOneToManyInfo() {
|
||||
ClassMapping inverse = field.getValueMapping().getTypeMapping();
|
||||
FieldMapping[] fmds = inverse.getFieldMappings();
|
||||
for (int i = 0; i < fmds.length; i++) {
|
||||
if (field == fmds[i].getMappedByMapping()) {
|
||||
int typeCode = fmds[i].getDeclaredTypeCode();
|
||||
if (typeCode == JavaTypes.ARRAY ||
|
||||
typeCode == JavaTypes.COLLECTION ||
|
||||
typeCode == JavaTypes.MAP) {
|
||||
// this is a bi-directional oneToMany relation with
|
||||
// @JoinTable annotation ==> join table strategy
|
||||
// ==> should not mapped in the owner's table
|
||||
FieldMappingInfo info = fmds[i].getMappingInfo();
|
||||
if (info.getTableName() != null)
|
||||
_biOneToManyJoinTable = i;
|
||||
_biOneToManyElemFK = fmds[i].getElementMapping().getForeignKey();
|
||||
_biOneToManyJoinFK = fmds[i].getJoinForeignKey();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object toDataStoreValue(Object val, JDBCStore store) {
|
||||
return RelationStrategies.toDataStoreValue(field, val, store);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue