mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1142 - Mapping - Add support for @OrderColumn (Ebean automatically maintains an order column)
This commit is contained in:
@@ -308,6 +308,7 @@ public class BeanDescriptor<T> implements BeanType<T> {
|
||||
|
||||
|
||||
private final BeanPropertyAssocOne<?> unidirectional;
|
||||
private final BeanProperty orderColumn;
|
||||
|
||||
/**
|
||||
* list of properties that are Lists/Sets/Maps (Derived).
|
||||
@@ -480,6 +481,7 @@ public class BeanDescriptor<T> implements BeanType<T> {
|
||||
this.propertiesLocal = listHelper.getLocal();
|
||||
this.propertiesMutable = listHelper.getMutable();
|
||||
this.unidirectional = listHelper.getUnidirectional();
|
||||
this.orderColumn = listHelper.getOrderColumn();
|
||||
this.propertiesOne = listHelper.getOnes();
|
||||
this.propertiesOneExportedSave = listHelper.getOneExportedSave();
|
||||
this.propertiesOneExportedDelete = listHelper.getOneExportedDelete();
|
||||
@@ -1925,6 +1927,13 @@ public class BeanDescriptor<T> implements BeanType<T> {
|
||||
return owner.getBeanDescriptor(otherType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order column property.
|
||||
*/
|
||||
public BeanProperty getOrderColumn() {
|
||||
return orderColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the "shadow" property to support unidirectional relationships.
|
||||
* <p>
|
||||
|
||||
@@ -38,6 +38,7 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssoc;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanTable;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployOrderColumn;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployTableJoin;
|
||||
import io.ebeaninternal.server.deploy.parse.DeployBeanInfo;
|
||||
import io.ebeaninternal.server.deploy.parse.DeployCreateProperties;
|
||||
@@ -50,6 +51,7 @@ import io.ebeaninternal.server.properties.BeanPropertiesReader;
|
||||
import io.ebeaninternal.server.properties.BeanPropertyAccess;
|
||||
import io.ebeaninternal.server.properties.EnhanceBeanPropertyAccess;
|
||||
import io.ebeaninternal.server.query.CQueryPlan;
|
||||
import io.ebeaninternal.server.type.ScalarTypeInteger;
|
||||
import io.ebeaninternal.xmlmapping.XmlMappingReader;
|
||||
import io.ebeaninternal.xmlmapping.model.XmAliasMapping;
|
||||
import io.ebeaninternal.xmlmapping.model.XmColumnMapping;
|
||||
@@ -979,6 +981,23 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
|
||||
private void makeOrderColumn(DeployBeanPropertyAssocMany<?> oneToMany) {
|
||||
|
||||
DeployBeanDescriptor<?> targetDesc = getTargetDescriptor(oneToMany);
|
||||
|
||||
DeployOrderColumn orderColumn = oneToMany.getOrderColumn();
|
||||
DeployBeanProperty orderProperty = new DeployBeanProperty(targetDesc, Integer.class, ScalarTypeInteger.INSTANCE, null);
|
||||
|
||||
orderProperty.setName(DeployOrderColumn.LOGICAL_NAME);
|
||||
orderProperty.setDbColumn(orderColumn.getName());
|
||||
orderProperty.setNullable(orderColumn.isNullable());
|
||||
orderProperty.setDbInsertable(orderColumn.isInsertable());
|
||||
orderProperty.setDbUpdateable(orderColumn.isUpdatable());
|
||||
orderProperty.setDbRead(true);
|
||||
|
||||
targetDesc.setOrderColumn(orderProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* A OneToMany with no matching mappedBy property in the target so must be
|
||||
* unidirectional.
|
||||
@@ -1112,6 +1131,10 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
prop.getCascadeInfo().setSaveDelete(true, true);
|
||||
}
|
||||
|
||||
if (prop.hasOrderColumn()) {
|
||||
makeOrderColumn(prop);
|
||||
}
|
||||
|
||||
if (prop.getMappedBy() == null) {
|
||||
// if we are doc store only we are done
|
||||
// this allowes the use of @OneToMany in @DocStore - Entities
|
||||
|
||||
@@ -58,6 +58,11 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
*/
|
||||
private final boolean unidirectional;
|
||||
|
||||
/**
|
||||
* Flag to indicate that the target has a order column to auto populate.
|
||||
*/
|
||||
private final boolean hasOrderColumn;
|
||||
|
||||
/**
|
||||
* Flag to indicate manyToMany relationship.
|
||||
*/
|
||||
@@ -109,6 +114,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
public BeanPropertyAssocMany(BeanDescriptor<?> descriptor, DeployBeanPropertyAssocMany<T> deploy) {
|
||||
super(descriptor, deploy);
|
||||
this.unidirectional = deploy.isUnidirectional();
|
||||
this.hasOrderColumn = deploy.hasOrderColumn();
|
||||
this.manyToMany = deploy.isManyToMany();
|
||||
this.manyType = deploy.getManyType();
|
||||
this.mapKey = deploy.getMapKey();
|
||||
@@ -534,6 +540,10 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasOrderColumn() {
|
||||
return hasOrderColumn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssocMany() {
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
|
||||
/**
|
||||
* Bean property for synthetic sort order value / order column.
|
||||
*
|
||||
* The value of which is held on the entity bean intercept.
|
||||
*/
|
||||
public class BeanPropertyOrderColumn extends BeanProperty {
|
||||
|
||||
public BeanPropertyOrderColumn(BeanDescriptor<?> descriptor, DeployBeanProperty deploy) {
|
||||
super(descriptor, deploy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(EntityBean bean) {
|
||||
return bean._ebean_getIntercept().getSortOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueIntercept(EntityBean bean) {
|
||||
return bean._ebean_getIntercept().getSortOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(EntityBean bean, Object value) {
|
||||
bean._ebean_getIntercept().setSortOrder((int)value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueIntercept(EntityBean bean, Object value) {
|
||||
bean._ebean_getIntercept().setSortOrder((int)value);
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,8 @@ public class DeployBeanDescriptor<T> {
|
||||
|
||||
private DeployBeanPropertyAssocOne<?> unidirectional;
|
||||
|
||||
private DeployBeanProperty orderColumn;
|
||||
|
||||
/**
|
||||
* Type of Identity generation strategy used.
|
||||
*/
|
||||
@@ -446,6 +448,14 @@ public class DeployBeanDescriptor<T> {
|
||||
this.unidirectional = unidirectional;
|
||||
}
|
||||
|
||||
public void setOrderColumn(DeployBeanProperty orderColumn) {
|
||||
this.orderColumn = orderColumn;
|
||||
}
|
||||
|
||||
public DeployBeanProperty getOrderColumn() {
|
||||
return orderColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the concurrency mode used for beans of this type.
|
||||
*/
|
||||
|
||||
@@ -12,35 +12,37 @@ public class DeployBeanPropertyAssocMany<T> extends DeployBeanPropertyAssoc<T> {
|
||||
/**
|
||||
* The type of the many, set, list or map.
|
||||
*/
|
||||
final ManyType manyType;
|
||||
private final ManyType manyType;
|
||||
|
||||
ModifyListenMode modifyListenMode = ModifyListenMode.NONE;
|
||||
|
||||
/**
|
||||
* Flag to indicate manyToMany relationship.
|
||||
*/
|
||||
boolean manyToMany;
|
||||
private boolean manyToMany;
|
||||
|
||||
/**
|
||||
* Flag to indicate this is a unidirectional relationship.
|
||||
*/
|
||||
boolean unidirectional;
|
||||
private boolean unidirectional;
|
||||
|
||||
/**
|
||||
* Join for manyToMany intersection table.
|
||||
*/
|
||||
DeployTableJoin intersectionJoin;
|
||||
private DeployTableJoin intersectionJoin;
|
||||
|
||||
/**
|
||||
* For ManyToMany this is the Inverse join used to build reference queries.
|
||||
*/
|
||||
DeployTableJoin inverseJoin;
|
||||
private DeployTableJoin inverseJoin;
|
||||
|
||||
String fetchOrderBy;
|
||||
private String fetchOrderBy;
|
||||
|
||||
String mapKey;
|
||||
private String mapKey;
|
||||
|
||||
String intersectionDraftTable;
|
||||
private String intersectionDraftTable;
|
||||
|
||||
private DeployOrderColumn orderColumn;
|
||||
|
||||
/**
|
||||
* Create this property.
|
||||
@@ -206,4 +208,16 @@ public class DeployBeanPropertyAssocMany<T> extends DeployBeanPropertyAssoc<T> {
|
||||
public void setIntersectionDraftTable() {
|
||||
this.intersectionDraftTable = intersectionJoin.getTable() + "_draft";
|
||||
}
|
||||
|
||||
public void setOrderColumn(DeployOrderColumn orderColumn) {
|
||||
this.orderColumn = orderColumn;
|
||||
}
|
||||
|
||||
public DeployOrderColumn getOrderColumn() {
|
||||
return orderColumn;
|
||||
}
|
||||
|
||||
public boolean hasOrderColumn() {
|
||||
return orderColumn != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.ebeaninternal.server.deploy.BeanDescriptorMap;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyOrderColumn;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertySimpleCollection;
|
||||
import io.ebeaninternal.server.deploy.InheritInfo;
|
||||
import io.ebeaninternal.server.deploy.TableJoin;
|
||||
@@ -64,6 +65,7 @@ public class DeployBeanPropertyLists {
|
||||
private final TableJoin[] tableJoins;
|
||||
|
||||
private final BeanPropertyAssocOne<?> unidirectional;
|
||||
private final BeanProperty orderColumn;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public DeployBeanPropertyLists(BeanDescriptorMap owner, BeanDescriptor<?> desc, DeployBeanDescriptor<?> deploy) {
|
||||
@@ -71,12 +73,11 @@ public class DeployBeanPropertyLists {
|
||||
|
||||
setImportedPrimaryKeys(deploy);
|
||||
|
||||
DeployBeanProperty deployOrderColumn = deploy.getOrderColumn();
|
||||
this.orderColumn = deployOrderColumn != null ? new BeanPropertyOrderColumn(desc, deployOrderColumn) : null;
|
||||
|
||||
DeployBeanPropertyAssocOne<?> deployUnidirectional = deploy.getUnidirectional();
|
||||
if (deployUnidirectional == null) {
|
||||
unidirectional = null;
|
||||
} else {
|
||||
unidirectional = new BeanPropertyAssocOne(owner, desc, deployUnidirectional);
|
||||
}
|
||||
this.unidirectional = deployUnidirectional == null ? null : new BeanPropertyAssocOne(owner, desc, deployUnidirectional);
|
||||
|
||||
this.propertyMap = new LinkedHashMap<>();
|
||||
|
||||
@@ -89,7 +90,7 @@ public class DeployBeanPropertyLists {
|
||||
// Create a BeanProperty for the discriminator column to support
|
||||
// using RawSql queries with inheritance
|
||||
discriminatorColumn = inheritInfo.getDiscriminatorColumn();
|
||||
DeployBeanProperty discDeployProp = new DeployBeanProperty(deploy, String.class, new ScalarTypeString(), null);
|
||||
DeployBeanProperty discDeployProp = new DeployBeanProperty(deploy, String.class, ScalarTypeString.INSTANCE, null);
|
||||
discDeployProp.setDiscriminator();
|
||||
discDeployProp.setName(discriminatorColumn);
|
||||
discDeployProp.setDbColumn(discriminatorColumn);
|
||||
@@ -115,6 +116,12 @@ public class DeployBeanPropertyLists {
|
||||
allocateToList(prop);
|
||||
}
|
||||
|
||||
if (orderColumn != null) {
|
||||
orderColumn.setDeployOrder(order++);
|
||||
allocateToList(orderColumn);
|
||||
propertyMap.put(orderColumn.getName(), orderColumn);
|
||||
}
|
||||
|
||||
if (discProperty != null) {
|
||||
// put the discriminator property into the property map only
|
||||
// (after the real properties have been organised into their lists)
|
||||
@@ -160,6 +167,13 @@ public class DeployBeanPropertyLists {
|
||||
return unidirectional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order column property.
|
||||
*/
|
||||
public BeanProperty getOrderColumn() {
|
||||
return orderColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the property to a list.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package io.ebeaninternal.server.deploy.meta;
|
||||
|
||||
import javax.persistence.OrderColumn;
|
||||
|
||||
public class DeployOrderColumn {
|
||||
|
||||
/**
|
||||
* Logical property name used for order by and available for expression language.
|
||||
*/
|
||||
public static final String LOGICAL_NAME = "orderColumn";
|
||||
|
||||
private final String name;
|
||||
private final boolean insertable;
|
||||
private final boolean updatable;
|
||||
private final boolean nullable;
|
||||
|
||||
public DeployOrderColumn(OrderColumn orderColumn) {
|
||||
this.name = orderColumn.name();
|
||||
this.insertable = orderColumn.insertable();
|
||||
this.updatable = orderColumn.updatable();
|
||||
this.nullable = orderColumn.nullable();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isInsertable() {
|
||||
return insertable;
|
||||
}
|
||||
|
||||
public boolean isUpdatable() {
|
||||
return updatable;
|
||||
}
|
||||
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
}
|
||||
@@ -13,16 +13,19 @@ import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanTable;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployOrderColumn;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployTableJoin;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployTableJoinColumn;
|
||||
import io.ebeaninternal.server.query.SqlJoinType;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.MapKey;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OrderBy;
|
||||
import javax.persistence.OrderColumn;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -66,6 +69,14 @@ class AnnotationAssocManys extends AnnotationParser {
|
||||
prop.setModifyListenMode(ModifyListenMode.REMOVALS);
|
||||
prop.getCascadeInfo().setDelete(privateOwned.cascadeRemove());
|
||||
}
|
||||
OrderColumn orderColumn = get(prop, OrderColumn.class);
|
||||
if (orderColumn != null) {
|
||||
// need to cascade as we set the order on cascade
|
||||
prop.setOrderColumn(new DeployOrderColumn(orderColumn));
|
||||
prop.setFetchOrderBy(DeployOrderColumn.LOGICAL_NAME);
|
||||
prop.getCascadeInfo().setType(CascadeType.ALL);
|
||||
prop.setModifyListenMode(ModifyListenMode.ALL);
|
||||
}
|
||||
}
|
||||
ManyToMany manyToMany = get(prop, ManyToMany.class);
|
||||
if (manyToMany != null) {
|
||||
|
||||
Reference in New Issue
Block a user