mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11586fb635 | ||
|
|
d555122067 | ||
|
|
b6d3dc3516 | ||
|
|
bbf54d6196 | ||
|
|
74c88ce511 | ||
|
|
309bf6a11a | ||
|
|
02b6ab0f74 | ||
|
|
0c41993ce7 | ||
|
|
d949c48245 | ||
|
|
93e603ca25 | ||
|
|
117d22fd67 | ||
|
|
f13de2c8a6 | ||
|
|
5b8ef8154a | ||
|
|
df892f4509 | ||
|
|
2755e6d1ec | ||
|
|
2024193da9 | ||
|
|
72788c7428 | ||
|
|
8789709fb8 | ||
|
|
588aaf9361 | ||
|
|
68649d0e98 | ||
|
|
f6047d3b73 | ||
|
|
629e096e28 | ||
|
|
c981944c8e | ||
|
|
1ba9f4e9de | ||
|
|
ce02e7ce70 | ||
|
|
1d9a2ed43a | ||
|
|
ae81ce5f47 | ||
|
|
9e42f98902 |
@@ -9,7 +9,7 @@
|
||||
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>11.18.2</version>
|
||||
<version>11.18.5</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>ebean</name>
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-11.18.2</tag>
|
||||
<tag>ebean-11.18.5</tag>
|
||||
</scm>
|
||||
|
||||
<profiles>
|
||||
@@ -135,7 +135,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>11.6.1</version>
|
||||
<version>11.7.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -133,8 +133,7 @@ public class VisitAllUsing {
|
||||
InheritInfo inheritInfo = descriptor.getInheritInfo();
|
||||
if (inheritInfo != null && inheritInfo.isRoot()) {
|
||||
// add all properties on the children objects
|
||||
InheritChildVisitor childVisitor = new InheritChildVisitor(this, pv);
|
||||
inheritInfo.visitChildren(childVisitor);
|
||||
inheritInfo.visitChildren(new InheritChildVisitor(this, pv));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,9 +154,10 @@ public class VisitAllUsing {
|
||||
|
||||
@Override
|
||||
public void visit(InheritInfo inheritInfo) {
|
||||
BeanProperty[] propertiesLocal = inheritInfo.desc().propertiesLocal();
|
||||
for (BeanProperty aPropertiesLocal : propertiesLocal) {
|
||||
owner.visit(pv, aPropertiesLocal);
|
||||
for (BeanProperty beanProperty : inheritInfo.desc().propertiesLocal()) {
|
||||
if (beanProperty.isDDLColumn()) {
|
||||
owner.visit(pv, beanProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1384,7 +1384,18 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
request.markNotQueryOnly();
|
||||
return request.delete();
|
||||
if (request.isDeleteByStatement()) {
|
||||
return request.delete();
|
||||
} else {
|
||||
// escalate to fetch the ids of the beans to delete due
|
||||
// to cascading deletes or l2 caching etc
|
||||
List<Object> ids = request.findIds();
|
||||
if (ids.isEmpty()) {
|
||||
return 0;
|
||||
} else {
|
||||
return persister.deleteByIds(request.getBeanDescriptor(), ids, request.getTransaction(), false);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
request.endTransIfRequired();
|
||||
}
|
||||
|
||||
@@ -116,6 +116,11 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeleteByStatement() {
|
||||
return beanDescriptor.isDeleteByStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultiValueIdSupported() {
|
||||
return beanDescriptor.isMultiValueIdSupported();
|
||||
|
||||
@@ -356,7 +356,15 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
|
||||
private boolean flushBatchOnGetter(int propertyIndex) {
|
||||
// propertyIndex of -1 the Id property, no flush for get Id on UPDATE
|
||||
return propertyIndex == -1 ? type == Type.INSERT : beanDescriptor.isGeneratedProperty(propertyIndex);
|
||||
if (propertyIndex == -1) {
|
||||
if (beanDescriptor.isIdLoaded(intercept)) {
|
||||
return false;
|
||||
} else {
|
||||
return type == Type.INSERT;
|
||||
}
|
||||
} else {
|
||||
return beanDescriptor.isGeneratedProperty(propertyIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSkipBatchForTopLevel() {
|
||||
|
||||
@@ -63,6 +63,11 @@ public interface Persister {
|
||||
*/
|
||||
int deleteMany(Class<?> beanType, Collection<?> ids, Transaction transaction, boolean permanent);
|
||||
|
||||
/**
|
||||
* Delete multiple beans when escalated from a delete query.
|
||||
*/
|
||||
int deleteByIds(BeanDescriptor<?> descriptor, List<Object> idList, Transaction transaction, boolean permanent);
|
||||
|
||||
/**
|
||||
* Execute the Update.
|
||||
*/
|
||||
|
||||
@@ -171,4 +171,9 @@ public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T>, DocQueryRequ
|
||||
* Set profile location for "find all" if not set.
|
||||
*/
|
||||
void profileLocationAll();
|
||||
|
||||
/**
|
||||
* Return true if delete by statement is allowed for this type given cascade rules etc.
|
||||
*/
|
||||
boolean isDeleteByStatement();
|
||||
}
|
||||
|
||||
@@ -291,6 +291,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
*/
|
||||
protected final InheritInfo inheritInfo;
|
||||
|
||||
private final boolean abstractType;
|
||||
|
||||
/**
|
||||
* Derived list of properties that make up the unique id.
|
||||
*/
|
||||
@@ -546,7 +548,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
this.whenCreatedProperty = findWhenCreatedProperty();
|
||||
|
||||
// derive the index position of the Id and Version properties
|
||||
if (Modifier.isAbstract(beanType.getModifiers())) {
|
||||
this.abstractType = Modifier.isAbstract(beanType.getModifiers());
|
||||
if (abstractType) {
|
||||
this.idPropertyIndex = -1;
|
||||
this.versionPropertyIndex = -1;
|
||||
this.unloadProperties = new int[0];
|
||||
@@ -653,6 +656,13 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
return ebeanServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is an abstract type.
|
||||
*/
|
||||
public boolean isAbstractType() {
|
||||
return abstractType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is a "Doc Store only" entity bean.
|
||||
*/
|
||||
@@ -3150,6 +3160,10 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
public boolean hasIdPropertyOnly(EntityBeanIntercept ebi) {
|
||||
return ebi.hasIdOnly(idPropertyIndex);
|
||||
}
|
||||
|
||||
public boolean isIdLoaded(EntityBeanIntercept ebi) {
|
||||
return ebi.isLoadedProperty(idPropertyIndex);
|
||||
}
|
||||
|
||||
public boolean hasIdValue(EntityBean bean) {
|
||||
return (idProperty != null && !DmlUtil.isNullOrZero(idProperty.getValue(bean)));
|
||||
@@ -3433,11 +3447,11 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
}
|
||||
|
||||
public T jsonRead(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return jsonHelp.jsonRead(jsonRead, path);
|
||||
return jsonHelp.jsonRead(jsonRead, path, true);
|
||||
}
|
||||
|
||||
protected T jsonReadObject(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return jsonHelp.jsonReadObject(jsonRead, path);
|
||||
public T jsonReadObject(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return jsonHelp.jsonRead(jsonRead, path, false);
|
||||
}
|
||||
|
||||
public List<BeanProperty[]> getUniqueProps() {
|
||||
|
||||
@@ -739,6 +739,7 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
if (invalidateQueryCache) {
|
||||
changeSet.addInvalidate(desc);
|
||||
} else {
|
||||
queryCacheClear(changeSet);
|
||||
if (beanCache != null) {
|
||||
changeSet.addBeanRemoveMany(desc, ids);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package io.ebeaninternal.server.deploy;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.text.json.EJson;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
@@ -12,18 +14,18 @@ import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BeanDescriptorJsonHelp<T> {
|
||||
class BeanDescriptorJsonHelp<T> {
|
||||
|
||||
private final BeanDescriptor<T> desc;
|
||||
|
||||
private final InheritInfo inheritInfo;
|
||||
|
||||
public BeanDescriptorJsonHelp(BeanDescriptor<T> desc) {
|
||||
BeanDescriptorJsonHelp(BeanDescriptor<T> desc) {
|
||||
this.desc = desc;
|
||||
this.inheritInfo = desc.inheritInfo;
|
||||
}
|
||||
|
||||
public void jsonWrite(SpiJsonWriter writeJson, EntityBean bean, String key) throws IOException {
|
||||
void jsonWrite(SpiJsonWriter writeJson, EntityBean bean, String key) throws IOException {
|
||||
|
||||
writeJson.writeStartObject(key);
|
||||
|
||||
@@ -42,13 +44,11 @@ public class BeanDescriptorJsonHelp<T> {
|
||||
writeJson.writeEndObject();
|
||||
}
|
||||
|
||||
protected void jsonWriteProperties(SpiJsonWriter writeJson, EntityBean bean) throws IOException {
|
||||
|
||||
void jsonWriteProperties(SpiJsonWriter writeJson, EntityBean bean) {
|
||||
writeJson.writeBean(desc, bean);
|
||||
}
|
||||
|
||||
public void jsonWriteDirty(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
|
||||
|
||||
void jsonWriteDirty(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
|
||||
if (inheritInfo == null) {
|
||||
jsonWriteDirtyProperties(writeJson, bean, dirtyProps);
|
||||
} else {
|
||||
@@ -56,7 +56,7 @@ public class BeanDescriptorJsonHelp<T> {
|
||||
}
|
||||
}
|
||||
|
||||
protected void jsonWriteDirtyProperties(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
|
||||
void jsonWriteDirtyProperties(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
|
||||
|
||||
writeJson.writeStartObject(null);
|
||||
// render the dirty properties
|
||||
@@ -70,7 +70,7 @@ public class BeanDescriptorJsonHelp<T> {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T jsonRead(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
T jsonRead(SpiJsonReader jsonRead, String path, boolean withInheritance) throws IOException {
|
||||
|
||||
JsonParser parser = jsonRead.getParser();
|
||||
//noinspection StatementWithEmptyBody
|
||||
@@ -87,43 +87,39 @@ public class BeanDescriptorJsonHelp<T> {
|
||||
}
|
||||
}
|
||||
|
||||
if (desc.inheritInfo == null) {
|
||||
if (desc.inheritInfo == null || !withInheritance) {
|
||||
return jsonReadObject(jsonRead, path);
|
||||
}
|
||||
|
||||
ObjectNode node = jsonRead.getObjectMapper().readTree(parser);
|
||||
if (node.isNull()) {
|
||||
return null;
|
||||
}
|
||||
JsonParser newParser = node.traverse();
|
||||
SpiJsonReader newReader = jsonRead.forJson(newParser, false);
|
||||
|
||||
// check for the discriminator value to determine the correct sub type
|
||||
String discColumn = inheritInfo.getRoot().getDiscriminatorColumn();
|
||||
|
||||
if (parser.nextToken() != JsonToken.FIELD_NAME) {
|
||||
String msg = "Error reading inheritance discriminator - expected [" + discColumn + "] but no json key?";
|
||||
throw new JsonParseException(parser, msg, parser.getCurrentLocation());
|
||||
}
|
||||
|
||||
String propName = parser.getCurrentName();
|
||||
if (!propName.equalsIgnoreCase(discColumn)) {
|
||||
// just try to assume this is the correct bean type in the inheritance
|
||||
BeanProperty property = desc.getBeanProperty(propName);
|
||||
if (property != null) {
|
||||
EntityBean bean = desc.createEntityBean();
|
||||
property.jsonRead(jsonRead, bean);
|
||||
return jsonReadProperties(jsonRead, bean, path);
|
||||
JsonNode discNode = node.get(discColumn);
|
||||
if (discNode == null || discNode.isNull()) {
|
||||
if (!desc.isAbstractType()) {
|
||||
return desc.jsonReadObject(newReader, path);
|
||||
}
|
||||
String msg = "Error reading inheritance discriminator, expected property [" + discColumn + "] but got [" + propName + "] ?";
|
||||
throw new JsonParseException(parser, msg, parser.getCurrentLocation());
|
||||
String msg = "Error reading inheritance discriminator - expected [" + discColumn + "] but no json key?";
|
||||
throw new JsonParseException(newParser, msg, parser.getCurrentLocation());
|
||||
}
|
||||
|
||||
String discValue = parser.nextTextValue();
|
||||
return (T) inheritInfo.readType(discValue).desc().jsonReadObject(jsonRead, path);
|
||||
return (T) inheritInfo.readType(discNode.asText()).desc().jsonReadObject(newReader, path);
|
||||
}
|
||||
|
||||
protected T jsonReadObject(SpiJsonReader readJson, String path) throws IOException {
|
||||
private T jsonReadObject(SpiJsonReader readJson, String path) throws IOException {
|
||||
|
||||
EntityBean bean = desc.createEntityBeanForJson();
|
||||
return jsonReadProperties(readJson, bean, path);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T jsonReadProperties(SpiJsonReader readJson, EntityBean bean, String path) throws IOException {
|
||||
private T jsonReadProperties(SpiJsonReader readJson, EntityBean bean, String path) throws IOException {
|
||||
|
||||
if (path != null) {
|
||||
readJson.pushPath(path);
|
||||
|
||||
@@ -187,6 +187,6 @@ public abstract class DeployParser {
|
||||
}
|
||||
|
||||
private boolean isWordStart(char ch) {
|
||||
return Character.isLetter(ch);
|
||||
return Character.isLetter(ch) || ch == UNDERSCORE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,6 @@ public class InheritInfo {
|
||||
* Set the descriptor for this node.
|
||||
*/
|
||||
public void setDescriptor(BeanDescriptor<?> descriptor) {
|
||||
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.deploy.meta;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptorMap;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
@@ -11,6 +12,7 @@ import io.ebeaninternal.server.deploy.BeanPropertySimpleCollection;
|
||||
import io.ebeaninternal.server.deploy.InheritInfo;
|
||||
import io.ebeaninternal.server.deploy.TableJoin;
|
||||
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
|
||||
import io.ebeaninternal.server.properties.BeanPropertySetter;
|
||||
import io.ebeaninternal.server.type.ScalarTypeString;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -26,6 +28,8 @@ public class DeployBeanPropertyLists {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DeployBeanPropertyLists.class);
|
||||
|
||||
private static final NoopSetter NOOP_SETTER = new NoopSetter();
|
||||
|
||||
private BeanProperty versionProperty;
|
||||
|
||||
private BeanProperty unmappedJson;
|
||||
@@ -100,6 +104,7 @@ public class DeployBeanPropertyLists {
|
||||
discDeployProp.setDiscriminator();
|
||||
discDeployProp.setName(discriminatorColumn);
|
||||
discDeployProp.setDbColumn(discriminatorColumn);
|
||||
discDeployProp.setSetter(NOOP_SETTER);
|
||||
|
||||
// only register it in the propertyMap. This might not be used if
|
||||
// an explicit property is mapped to the discriminator on the bean
|
||||
@@ -491,4 +496,17 @@ public class DeployBeanPropertyLists {
|
||||
|
||||
return new BeanProperty(desc, deployProp);
|
||||
}
|
||||
|
||||
private static class NoopSetter implements BeanPropertySetter {
|
||||
|
||||
@Override
|
||||
public void set(EntityBean bean, Object value) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIntercept(EntityBean bean, Object value) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -680,6 +680,12 @@ public final class DefaultPersister implements Persister {
|
||||
return delete(descriptor, id, null, transaction, deleteMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteByIds(BeanDescriptor<?> descriptor, List<Object> idList, Transaction transaction, boolean permanent) {
|
||||
DeleteMode deleteMode = (permanent || !descriptor.isSoftDelete()) ? DeleteMode.HARD : DeleteMode.SOFT;
|
||||
return delete(descriptor, null, idList, transaction, deleteMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete by Id or a List of Id's.
|
||||
*/
|
||||
@@ -739,18 +745,20 @@ public final class DefaultPersister implements Persister {
|
||||
// OneToMany's with delete cascade
|
||||
BeanPropertyAssocMany<?>[] manys = descriptor.propertiesManyDelete();
|
||||
for (BeanPropertyAssocMany<?> many : manys) {
|
||||
BeanDescriptor<?> targetDesc = many.getTargetDescriptor();
|
||||
// only cascade soft deletes when supported by target
|
||||
if (deleteMode.isHard() || targetDesc.isSoftDelete()) {
|
||||
if (deleteMode.isHard() && targetDesc.isDeleteByStatement()) {
|
||||
// we can just delete children with a single statement
|
||||
SqlUpdate sqlDelete = many.deleteByParentId(id, idList);
|
||||
executeSqlUpdate(sqlDelete, t);
|
||||
} else {
|
||||
// we need to fetch the Id's to delete (recurse or notify L2 cache)
|
||||
List<Object> childIds = many.findIdsByParentId(id, idList, t, null);
|
||||
if (!childIds.isEmpty()) {
|
||||
delete(targetDesc, null, childIds, t, deleteMode);
|
||||
if (!many.isManyToMany()) {
|
||||
BeanDescriptor<?> targetDesc = many.getTargetDescriptor();
|
||||
// only cascade soft deletes when supported by target
|
||||
if (deleteMode.isHard() || targetDesc.isSoftDelete()) {
|
||||
if (deleteMode.isHard() && targetDesc.isDeleteByStatement()) {
|
||||
// we can just delete children with a single statement
|
||||
SqlUpdate sqlDelete = many.deleteByParentId(id, idList);
|
||||
executeSqlUpdate(sqlDelete, t);
|
||||
} else {
|
||||
// we need to fetch the Id's to delete (recurse or notify L2 cache)
|
||||
List<Object> childIds = many.findIdsByParentId(id, idList, t, null);
|
||||
if (!childIds.isEmpty()) {
|
||||
delete(targetDesc, null, childIds, t, deleteMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.query;
|
||||
|
||||
import io.ebean.OrderBy;
|
||||
import io.ebean.OrderBy.Property;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
@@ -18,27 +17,22 @@ class CQueryOrderBy {
|
||||
|
||||
private final BeanDescriptor<?> desc;
|
||||
|
||||
private final SpiQuery<?> query;
|
||||
private final OrderBy<?> orderBy;
|
||||
|
||||
/**
|
||||
* Create the logical order by clause.
|
||||
*/
|
||||
public static String parse(BeanDescriptor<?> desc, SpiQuery<?> query) {
|
||||
return new CQueryOrderBy(desc, query).parseInternal();
|
||||
public static String parse(BeanDescriptor<?> desc, OrderBy<?> orderBy) {
|
||||
return new CQueryOrderBy(desc, orderBy).parseInternal();
|
||||
}
|
||||
|
||||
private CQueryOrderBy(BeanDescriptor<?> desc, SpiQuery<?> query) {
|
||||
private CQueryOrderBy(BeanDescriptor<?> desc, OrderBy<?> orderBy) {
|
||||
this.desc = desc;
|
||||
this.query = query;
|
||||
this.orderBy = orderBy;
|
||||
}
|
||||
|
||||
private String parseInternal() {
|
||||
|
||||
OrderBy<?> orderBy = query.getOrderBy();
|
||||
if (orderBy == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
List<Property> properties = orderBy.getProperties();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.query;
|
||||
|
||||
import io.ebean.OrderBy;
|
||||
import io.ebeaninternal.api.BindParams;
|
||||
import io.ebeaninternal.api.SpiExpressionList;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
@@ -329,7 +330,11 @@ public class CQueryPredicates {
|
||||
|
||||
private String parseOrderBy() {
|
||||
|
||||
return CQueryOrderBy.parse(request.getBeanDescriptor(), query);
|
||||
OrderBy<?> orderBy = query.getOrderBy();
|
||||
if (orderBy == null) {
|
||||
return null;
|
||||
}
|
||||
return CQueryOrderBy.parse(request.getBeanDescriptor(), orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,8 +47,6 @@ public class DJsonContext implements SpiJsonContext {
|
||||
|
||||
private final JsonFactory jsonFactory;
|
||||
|
||||
private final TypeManager typeManager;
|
||||
|
||||
private final Object defaultObjectMapper;
|
||||
|
||||
private final JsonConfig.Include defaultInclude;
|
||||
@@ -57,11 +55,10 @@ public class DJsonContext implements SpiJsonContext {
|
||||
|
||||
public DJsonContext(SpiEbeanServer server, JsonFactory jsonFactory, TypeManager typeManager) {
|
||||
this.server = server;
|
||||
this.typeManager = typeManager;
|
||||
this.jsonFactory = (jsonFactory != null) ? jsonFactory : new JsonFactory();
|
||||
this.defaultObjectMapper = this.server.getServerConfig().getObjectMapper();
|
||||
this.defaultInclude = this.server.getServerConfig().getJsonInclude();
|
||||
this.jsonScalar = new DJsonScalar(this.typeManager);
|
||||
this.jsonScalar = new DJsonScalar(typeManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -121,9 +118,8 @@ public class DJsonContext implements SpiJsonContext {
|
||||
public <T> T toBean(Class<T> cls, JsonParser parser, JsonReadOptions options) throws JsonIOException {
|
||||
|
||||
BeanDescriptor<T> desc = getDescriptor(cls);
|
||||
SpiJsonReader readJson = new ReadJson(desc, parser, options, determineObjectMapper(options));
|
||||
try {
|
||||
return desc.jsonRead(readJson, null);
|
||||
return desc.jsonRead(new ReadJson(desc, parser, options, determineObjectMapper(options)), null);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
@@ -133,8 +129,7 @@ public class DJsonContext implements SpiJsonContext {
|
||||
public <T> DJsonBeanReader<T> createBeanReader(Class<T> cls, JsonParser parser, JsonReadOptions options) throws JsonIOException {
|
||||
|
||||
BeanDescriptor<T> desc = getDescriptor(cls);
|
||||
SpiJsonReader readJson = new ReadJson(desc, parser, options, determineObjectMapper(options));
|
||||
return new DJsonBeanReader<>(desc, readJson);
|
||||
return new DJsonBeanReader<>(desc, new ReadJson(desc, parser, options, determineObjectMapper(options)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -354,8 +349,7 @@ public class DJsonContext implements SpiJsonContext {
|
||||
|
||||
@Override
|
||||
public SpiJsonWriter createJsonWriter(Writer writer) {
|
||||
JsonGenerator generator = createGenerator(writer);
|
||||
return createJsonWriter(generator, null);
|
||||
return createJsonWriter(createGenerator(writer), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -375,9 +369,7 @@ public class DJsonContext implements SpiJsonContext {
|
||||
gen.writeFieldName(key);
|
||||
}
|
||||
gen.writeStartArray();
|
||||
|
||||
WriteJson writeJson = createWriteJson(gen, options);
|
||||
|
||||
for (T bean : collection) {
|
||||
BeanDescriptor<?> d = getDescriptor(bean.getClass());
|
||||
d.jsonWrite(writeJson, (EntityBean) bean, null);
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.tests.basic.delete;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.Query;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.tests.model.onetoone.OtoUser;
|
||||
import org.tests.model.onetoone.OtoUserOptional;
|
||||
|
||||
public class TestDeleteCascadeByQuery extends BaseTestCase {
|
||||
|
||||
private OtoUser testUser;
|
||||
private OtoUserOptional userOptional;
|
||||
private Query<OtoUserOptional> userOptionalQuery = Ebean.find(OtoUserOptional.class);
|
||||
private Query<OtoUser> userQuery = Ebean.find(OtoUser.class);
|
||||
|
||||
/**
|
||||
* Init each test. Delete all existing beans. Then create OtoUser, add OtoUserOptional and save.
|
||||
*/
|
||||
@Before
|
||||
public void init() {
|
||||
Ebean.deleteAll(userQuery.findList());
|
||||
Ebean.deleteAll(userOptionalQuery.findList());
|
||||
|
||||
userOptional = new OtoUserOptional();
|
||||
Ebean.save(userOptional);
|
||||
testUser = new OtoUser();
|
||||
testUser.setOptional(userOptional);
|
||||
Ebean.save(testUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that validates deleting a bean using Ebean.delete() respects the CascadeType.DELETE
|
||||
* setting.
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteCascadeByEbeanDelete() {
|
||||
|
||||
assertThat(Ebean.delete(testUser)).isTrue();
|
||||
|
||||
assertThat(userOptionalQuery.findCount())
|
||||
.overridingErrorMessage("Entity OtoUserOptional found. Ebean.delete() on the user "
|
||||
+ "did not delete the OneToOne mapped entity as set with CascadeType.ALL")
|
||||
.isEqualTo(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that validates deleting a bean with OneToOne mapping with a query respects the
|
||||
* CascadeType.DELETE setting.
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteCascadeByQuery() {
|
||||
|
||||
assertThat(userQuery.delete()).isEqualTo(1);
|
||||
|
||||
assertThat(userOptionalQuery.findCount())
|
||||
.overridingErrorMessage("Entity OtoUserOptional found. Ebean query delete() on the user "
|
||||
+ "did not delete the OneToOne mapped entity as set with CascadeType.ALL")
|
||||
.isEqualTo(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup - Delete all existing beans for the next test.
|
||||
*/
|
||||
@After
|
||||
public void cleanup() {
|
||||
Ebean.deleteAll(userQuery.findList());
|
||||
Ebean.deleteAll(userOptionalQuery.findList());
|
||||
}
|
||||
}
|
||||
@@ -122,15 +122,20 @@ public class TestBatchInsertFlush extends BaseTestCase {
|
||||
public void transactional_flushOnGetId() {
|
||||
|
||||
EbeanServer server = Ebean.getDefaultServer();
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
EBasicVer b1 = new EBasicVer("b1");
|
||||
server.save(b1);
|
||||
|
||||
EBasicVer b2 = new EBasicVer("b2");
|
||||
server.save(b2);
|
||||
|
||||
//flush here
|
||||
assertThat(LoggedSqlCollector.current()).isEmpty();
|
||||
Integer id = b1.getId();
|
||||
assertNotNull(id);
|
||||
assertThat(LoggedSqlCollector.current()).hasSize(2);
|
||||
|
||||
EBasicVer b3 = new EBasicVer("b3");
|
||||
server.save(b3);
|
||||
}
|
||||
@@ -141,7 +146,8 @@ public class TestBatchInsertFlush extends BaseTestCase {
|
||||
EbeanServer server = Ebean.getDefaultServer();
|
||||
Transaction txn = server.beginTransaction();
|
||||
try {
|
||||
txn.setBatch(PersistBatch.ALL);
|
||||
LoggedSqlCollector.start();
|
||||
txn.setBatchMode(true);
|
||||
|
||||
EBasicVer b1 = new EBasicVer("b1");
|
||||
server.save(b1, txn);
|
||||
@@ -149,8 +155,11 @@ public class TestBatchInsertFlush extends BaseTestCase {
|
||||
EBasicVer b2 = new EBasicVer("b2");
|
||||
server.save(b2, txn);
|
||||
|
||||
//flush here
|
||||
assertThat(LoggedSqlCollector.current()).isEmpty();
|
||||
Integer id = b1.getId();
|
||||
assertNotNull(id);
|
||||
assertThat(LoggedSqlCollector.current()).hasSize(2);
|
||||
|
||||
EBasicVer b3 = new EBasicVer("b3");
|
||||
server.save(b3, txn);
|
||||
@@ -161,6 +170,67 @@ public class TestBatchInsertFlush extends BaseTestCase {
|
||||
txn.end();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional(batch = PersistBatch.ALL)
|
||||
public void transactional_noflushWhenIdIsLoaded() {
|
||||
|
||||
EbeanServer server = Ebean.getDefaultServer();
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
EBasicVer b1 = new EBasicVer("b1");
|
||||
b1.setId(78965);
|
||||
server.save(b1);
|
||||
|
||||
EBasicVer b2 = new EBasicVer("b2");
|
||||
b2.setId(78645);
|
||||
server.save(b2);
|
||||
|
||||
assertThat(LoggedSqlCollector.current()).isEmpty();
|
||||
// dont flush here
|
||||
Integer id = b1.getId();
|
||||
assertNotNull(id);
|
||||
assertThat(LoggedSqlCollector.current()).isEmpty();
|
||||
|
||||
EBasicVer b3 = new EBasicVer("b3");
|
||||
server.save(b3);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noflushWhenIdIsLoaded() {
|
||||
|
||||
EbeanServer server = Ebean.getDefaultServer();
|
||||
Transaction txn = server.beginTransaction();
|
||||
try {
|
||||
LoggedSqlCollector.start();
|
||||
txn.setBatchMode(true);
|
||||
|
||||
EBasicVer b1 = new EBasicVer("b1");
|
||||
b1.setId(546864);
|
||||
server.save(b1, txn);
|
||||
|
||||
EBasicVer b2 = new EBasicVer("b2");
|
||||
b2.setId(21354);
|
||||
server.save(b2, txn);
|
||||
|
||||
assertThat(LoggedSqlCollector.current()).isEmpty();
|
||||
//dont flush here
|
||||
Integer id = b1.getId();
|
||||
assertNotNull(id);
|
||||
assertThat(LoggedSqlCollector.current()).isEmpty();
|
||||
|
||||
EBasicVer b3 = new EBasicVer("b3");
|
||||
server.save(b3, txn);
|
||||
|
||||
txn.commit();
|
||||
assertThat(LoggedSqlCollector.current()).hasSize(3);
|
||||
|
||||
} finally {
|
||||
txn.end();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlushOnGetProperty() {
|
||||
|
||||
@@ -7,7 +7,9 @@ import io.ebean.Query;
|
||||
import io.ebean.annotation.IgnorePlatform;
|
||||
import io.ebean.annotation.Platform;
|
||||
|
||||
import org.tests.model.basic.BBookmarkUser;
|
||||
import org.tests.model.basic.Contact;
|
||||
import org.tests.model.basic.Country;
|
||||
import org.tests.model.basic.Customer;
|
||||
import org.tests.model.basic.ResetBasicData;
|
||||
import org.ebeantest.LoggedSqlCollector;
|
||||
@@ -22,7 +24,46 @@ public class TestDeleteByQuery extends BaseTestCase {
|
||||
@Test
|
||||
@IgnorePlatform(Platform.MYSQL)
|
||||
// FIXME: MySql does not the sub query selecting from the delete table
|
||||
public void test() {
|
||||
public void deleteWithSubquery() {
|
||||
|
||||
EbeanServer server = Ebean.getDefaultServer();
|
||||
|
||||
BBookmarkUser u1 = new BBookmarkUser("u1");
|
||||
Ebean.save(u1);
|
||||
|
||||
Query<BBookmarkUser> query = server.find(BBookmarkUser.class)
|
||||
.where().eq("org.name", "NahYeahMaybe")
|
||||
.query();
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
query.delete();
|
||||
|
||||
List<String> loggedSql = LoggedSqlCollector.stop();
|
||||
assertThat(loggedSql).hasSize(1);
|
||||
assertThat(trimSql(loggedSql.get(0), 1)).contains("delete from bbookmark_user where id in (select t0.id from bbookmark_user t0 left join bbookmark_org t1 on t1.id = t0.org_id where t1.name");
|
||||
|
||||
Query<BBookmarkUser> query2 = server.find(BBookmarkUser.class)
|
||||
.where().eq("name", "NotARealFirstName").query();
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
query2.delete();
|
||||
|
||||
loggedSql = LoggedSqlCollector.stop();
|
||||
assertThat(loggedSql).hasSize(1);
|
||||
assertThat(loggedSql.get(0)).contains("delete from bbookmark_user where name =");
|
||||
|
||||
|
||||
server.find(BBookmarkUser.class).select("id").where().eq("name", "NotARealFirstName").delete();
|
||||
server.find(BBookmarkUser.class).select("id").where().eq("name", "TwoAlsoNotRealFirstName").query().delete();
|
||||
|
||||
List<BBookmarkUser> list = server.find(BBookmarkUser.class).select("id").where().eq("name", "NotARealFirstName").findList();
|
||||
assertThat(list).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IgnorePlatform(Platform.MYSQL)
|
||||
// FIXME: MySql does not the sub query selecting from the delete table
|
||||
public void deleteWithSubquery_withEscalation() {
|
||||
|
||||
EbeanServer server = Ebean.getDefaultServer();
|
||||
|
||||
@@ -33,7 +74,7 @@ public class TestDeleteByQuery extends BaseTestCase {
|
||||
|
||||
List<String> loggedSql = LoggedSqlCollector.stop();
|
||||
assertThat(loggedSql).hasSize(1);
|
||||
assertThat(trimSql(loggedSql.get(0), 1)).contains("delete from contact where id in (select t0.id from contact t0 left join");
|
||||
assertThat(trimSql(loggedSql.get(0), 1)).contains("select t0.id from contact t0 left join contact_group t1 on t1.id = t0.group_id where t1.name = ?");
|
||||
|
||||
Query<Contact> query2 = server.find(Contact.class).where().eq("firstName", "NotARealFirstName").query();
|
||||
|
||||
@@ -42,7 +83,7 @@ public class TestDeleteByQuery extends BaseTestCase {
|
||||
|
||||
loggedSql = LoggedSqlCollector.stop();
|
||||
assertThat(loggedSql).hasSize(1);
|
||||
assertThat(loggedSql.get(0)).contains("delete from contact where first_name =");
|
||||
assertThat(loggedSql.get(0)).contains("select t0.id from contact t0 where t0.first_name = ?");
|
||||
|
||||
|
||||
server.find(Contact.class).select("id").where().eq("firstName", "NotARealFirstName").delete();
|
||||
@@ -57,12 +98,29 @@ public class TestDeleteByQuery extends BaseTestCase {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
Ebean.find(BBookmarkUser.class).where().eq("id", 7000).delete();
|
||||
Ebean.find(BBookmarkUser.class).setId(7000).delete();
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
assertThat(sql.get(0)).contains("delete from bbookmark_user where id = ?");
|
||||
assertThat(sql.get(1)).contains("delete from bbookmark_user where id = ?");
|
||||
|
||||
// and note this is the easiest option
|
||||
Ebean.delete(BBookmarkUser.class, 7000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryByIdDelete_withEscalation() {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
Ebean.find(Contact.class).where().eq("id", 7000).delete();
|
||||
Ebean.find(Contact.class).setId(7000).delete();
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
assertThat(sql.get(0)).contains("delete from contact where id = ?");
|
||||
assertThat(sql.get(1)).contains("delete from contact where id = ?");
|
||||
// escalate to fetch ids then delete ... but no rows found
|
||||
assertThat(sql.get(0)).contains("select t0.id from contact t0 where t0.id = ?");
|
||||
assertThat(sql.get(1)).contains("select t0.id from contact t0 where t0.id = ?");
|
||||
|
||||
// and note this is the easiest option
|
||||
Ebean.delete(Contact.class, 7000);
|
||||
@@ -80,11 +138,23 @@ public class TestDeleteByQuery extends BaseTestCase {
|
||||
|
||||
List<String> sql = LoggedSqlCollector.stop();
|
||||
assertThat(sql).hasSize(1);
|
||||
assertThat(sql.get(0)).contains("delete from o_customer where name = ?");
|
||||
assertThat(sql.get(0)).contains("select t0.id from o_customer t0 where t0.name = ?");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommit() {
|
||||
public void deleteByPredicate() {
|
||||
|
||||
BBookmarkUser ud = new BBookmarkUser("deleteQueryByPredicate");
|
||||
Ebean.save(ud);
|
||||
|
||||
Ebean.find(BBookmarkUser.class).where().eq("name", "deleteQueryByPredicate").delete();
|
||||
|
||||
BBookmarkUser found = Ebean.find(BBookmarkUser.class, ud.getId());
|
||||
assertThat(found).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteByPredicate_withEscalation() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
@@ -101,4 +171,22 @@ public class TestDeleteByQuery extends BaseTestCase {
|
||||
Contact contactFind = Ebean.find(Contact.class, contact.getId());
|
||||
assertThat(contactFind).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteByPredicateCached() {
|
||||
|
||||
Country country = new Country();
|
||||
country.setCode("XX");
|
||||
country.setName("SecretName");
|
||||
Ebean.save(country);
|
||||
Query<Country> query = Ebean.find(Country.class).where().eq("name", "SecretName").setUseQueryCache(true);
|
||||
|
||||
assertThat(query.findList()).hasSize(1);
|
||||
assertThat(query.findCount()).isEqualTo(1);
|
||||
|
||||
Ebean.find(Country.class).where().eq("name", "SecretName").delete();
|
||||
//Ebean.getDefaultServer().getPluginApi().getBeanType(Country.class).clearQueryCache();
|
||||
assertThat(query.findList()).hasSize(0);
|
||||
assertThat(query.findCount()).isEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,44 +26,26 @@ public class BBookmark {
|
||||
@Column
|
||||
private BBookmarkUser user;
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public Integer getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(final Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the bookmarkReference
|
||||
*/
|
||||
public String getBookmarkReference() {
|
||||
return this.bookmarkReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bookmarkReference the bookmarkReference to set
|
||||
*/
|
||||
public void setBookmarkReference(final String bookmarkReference) {
|
||||
this.bookmarkReference = bookmarkReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the user
|
||||
*/
|
||||
public BBookmarkUser getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param user the user to set
|
||||
*/
|
||||
public void setUser(final BBookmarkUser user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class BBookmarkOrg {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
public BBookmarkOrg(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
* represents a user entity. A user contains a username and password.
|
||||
*
|
||||
* @author Chris
|
||||
*/
|
||||
@Entity
|
||||
@@ -17,97 +15,69 @@ public class BBookmarkUser {
|
||||
@GeneratedValue
|
||||
private Integer id;
|
||||
|
||||
@Column
|
||||
private String name;
|
||||
|
||||
@Column
|
||||
private String password;
|
||||
|
||||
@Column
|
||||
private String emailAddress;
|
||||
|
||||
@Column
|
||||
private String country;
|
||||
|
||||
// @Version
|
||||
// private Timestamp lastUpdate;
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
* An optional non-cascading ManyToOne.
|
||||
*/
|
||||
@ManyToOne
|
||||
private BBookmarkOrg org;
|
||||
|
||||
public BBookmarkUser(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(final Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the password
|
||||
*/
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param password the password to set
|
||||
*/
|
||||
public void setPassword(final String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the emailAddress
|
||||
*/
|
||||
public String getEmailAddress() {
|
||||
return this.emailAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param emailAddress the emailAddress to set
|
||||
*/
|
||||
public void setEmailAddress(final String emailAddress) {
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the country
|
||||
*/
|
||||
public String getCountry() {
|
||||
return this.country;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param country the country to set
|
||||
*/
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
// public Timestamp getLastUpdate() {
|
||||
// return lastUpdate;
|
||||
// }
|
||||
//
|
||||
// public void setLastUpdate(Timestamp lastUpdate) {
|
||||
// this.lastUpdate = lastUpdate;
|
||||
// }
|
||||
public BBookmarkOrg getOrg() {
|
||||
return org;
|
||||
}
|
||||
|
||||
public void setOrg(BBookmarkOrg org) {
|
||||
this.org = org;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import io.ebean.annotation.Formula;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@@ -9,6 +11,9 @@ public class Cat extends Animal {
|
||||
|
||||
String name;
|
||||
|
||||
@Formula(select = "${ta}.species")
|
||||
String catFormula;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -17,4 +22,11 @@ public class Cat extends Animal {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCatFormula() {
|
||||
return catFormula;
|
||||
}
|
||||
|
||||
public void setCatFormula(String catFormula) {
|
||||
this.catFormula = catFormula;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,13 @@ import io.ebean.annotation.TxType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class DummyDao {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(DummyDao.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(DummyDao.class);
|
||||
|
||||
@Transactional(type = TxType.REQUIRES_NEW)
|
||||
public void doSomething() {
|
||||
@@ -30,18 +29,12 @@ public class DummyDao {
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void addToObject(Long id, Double anotherNumber, List<Long> ids) throws EntityNotFoundException {
|
||||
// and more code
|
||||
}
|
||||
|
||||
|
||||
@Transactional(batch = PersistBatch.ALL, batchOnCascade = PersistBatch.ALL, batchSize = 99)
|
||||
public void doWithBatchOptionsSet() {
|
||||
private void doWithBatchOptionsSet() {
|
||||
|
||||
Transaction txn = Ebean.currentTransaction();
|
||||
assertEquals(PersistBatch.ALL, txn.getBatch());
|
||||
assertEquals(PersistBatch.ALL, txn.getBatchOnCascade());
|
||||
assertTrue(txn.isBatchMode());
|
||||
assertTrue(txn.isBatchOnCascade());
|
||||
assertEquals(99, txn.getBatchSize());
|
||||
}
|
||||
|
||||
@@ -51,15 +44,15 @@ public class DummyDao {
|
||||
|
||||
Transaction txn = Ebean.currentTransaction();
|
||||
|
||||
assertEquals(PersistBatch.ALL, txn.getBatch());
|
||||
assertEquals(PersistBatch.NONE, txn.getBatchOnCascade());
|
||||
assertTrue(txn.isBatchMode());
|
||||
assertFalse(txn.isBatchOnCascade());
|
||||
assertEquals(77, txn.getBatchSize());
|
||||
|
||||
doWithBatchOptionsSet();
|
||||
|
||||
// batch options set back
|
||||
assertEquals(PersistBatch.ALL, txn.getBatch());
|
||||
assertEquals(PersistBatch.NONE, txn.getBatchOnCascade());
|
||||
assertTrue(txn.isBatchMode());
|
||||
assertFalse(txn.isBatchOnCascade());
|
||||
assertEquals(77, txn.getBatchSize());
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.tests.model.lazywithid;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class Looney {
|
||||
@Id
|
||||
public Long id;
|
||||
|
||||
@ManyToOne
|
||||
private Tune tune;
|
||||
|
||||
private String name;
|
||||
|
||||
public Looney(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Tune getTune() {
|
||||
return tune;
|
||||
}
|
||||
|
||||
public void setTune(final Tune tune) {
|
||||
this.tune = tune;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.tests.model.lazywithid;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
|
||||
public class TestColumnIdName extends BaseTestCase {
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
Tune tune = new Tune();
|
||||
tune.getLoonies().add(new Looney("Taz"));
|
||||
Ebean.save(tune);
|
||||
|
||||
final List<Tune> fetchedCollection = Ebean.find(Tune.class).findList();
|
||||
|
||||
assertEquals(1, fetchedCollection.size());
|
||||
assertEquals(1, fetchedCollection.get(0).getLoonies().size());
|
||||
assertEquals("Taz", fetchedCollection.get(0).getLoonies().get(0).getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.tests.model.lazywithid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
import io.ebean.common.BeanList;
|
||||
|
||||
@Entity
|
||||
public class Tune {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
Long _id;
|
||||
|
||||
String name;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
private List<Looney> loonies = new BeanList<>();
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Looney> getLoonies() {
|
||||
return loonies;
|
||||
}
|
||||
|
||||
public void setLoonies(final List<Looney> loonies) {
|
||||
this.loonies = loonies;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.tests.model.onetoone;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.tests.model.BaseModel;
|
||||
|
||||
@Entity
|
||||
@Table(name = "oto_user_model")
|
||||
public class OtoUser extends BaseModel {
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL)
|
||||
private OtoUserOptional userOptional;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setOptional(OtoUserOptional userOptional) {
|
||||
this.userOptional = userOptional;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.tests.model.onetoone;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.tests.model.BaseModel;
|
||||
|
||||
@Entity
|
||||
@Table(name = "oto_user_model_optional")
|
||||
public class OtoUserOptional extends BaseModel {
|
||||
|
||||
private String optional;
|
||||
|
||||
public void setPassword(final String optional) {
|
||||
this.optional = optional;
|
||||
}
|
||||
|
||||
public String getOptional() {
|
||||
return optional;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.tests.profile;
|
||||
|
||||
import org.tests.model.basic.Customer;
|
||||
//import org.tests.model.basic.ResetBasicData;
|
||||
|
||||
public class ProfileSimpleQuery {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// ResetBasicData.reset();
|
||||
ProfileSimpleQuery me = new ProfileSimpleQuery();
|
||||
me.runIt();
|
||||
|
||||
}
|
||||
|
||||
private long counter;
|
||||
|
||||
private void runIt() {
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < 1000_000; i++) {
|
||||
readCustomer();
|
||||
}
|
||||
long exe = System.currentTimeMillis() - start;
|
||||
System.out.println("run in " + exe);
|
||||
}
|
||||
|
||||
private void readCustomer() {
|
||||
Customer customer = Customer.find.byName("Rob");
|
||||
String name = customer.getName();
|
||||
if (name.length() > 999) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,20 +3,20 @@ package org.tests.text.json;
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.Animal;
|
||||
import org.tests.model.basic.Cat;
|
||||
import org.tests.model.basic.Dog;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestJsonInheritanceDiscriminator extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testNoDiscriminator() throws IOException {
|
||||
public void testNoDiscriminator() {
|
||||
|
||||
Cat cat = new Cat();
|
||||
cat.setName("Gemma");
|
||||
@@ -28,17 +28,17 @@ public class TestJsonInheritanceDiscriminator extends BaseTestCase {
|
||||
|
||||
Cat cat2 = json.toBean(Cat.class, jsonContent);
|
||||
|
||||
Assert.assertEquals(cat.getId(), cat2.getId());
|
||||
Assert.assertEquals(cat.getName(), cat2.getName());
|
||||
Assert.assertEquals(cat.getVersion(), cat2.getVersion());
|
||||
assertEquals(cat.getId(), cat2.getId());
|
||||
assertEquals(cat.getName(), cat2.getName());
|
||||
assertEquals(cat.getVersion(), cat2.getVersion());
|
||||
|
||||
String noDiscriminator = "{\"id\":1,\"name\":\"Gemma\",\"version\":1}";
|
||||
|
||||
Cat cat3 = json.toBean(Cat.class, noDiscriminator);
|
||||
|
||||
Assert.assertEquals(1L, cat3.getId().longValue());
|
||||
Assert.assertEquals("Gemma", cat3.getName());
|
||||
Assert.assertEquals(1L, cat3.getVersion().longValue());
|
||||
assertEquals(1L, cat3.getId().longValue());
|
||||
assertEquals("Gemma", cat3.getName());
|
||||
assertEquals(1L, cat3.getVersion().longValue());
|
||||
|
||||
Dog dog = new Dog();
|
||||
dog.setRegistrationNumber("ABC123");
|
||||
@@ -51,11 +51,11 @@ public class TestJsonInheritanceDiscriminator extends BaseTestCase {
|
||||
String listJson = json.toJson(animals);
|
||||
|
||||
List<Animal> animals2 = json.toList(Animal.class, listJson);
|
||||
Assert.assertEquals(animals.size(), animals2.size());
|
||||
assertEquals(animals.size(), animals2.size());
|
||||
|
||||
String noDiscList = "[{\"id\":1,\"name\":\"Gemma\",\"version\":1},{\"name\":\"PussCat\",\"version\":1},{\"species\":\"CAT\",\"name\":\"PussCat\",\"version\":1}]";
|
||||
List<Cat> cats = json.toList(Cat.class, noDiscList);
|
||||
Assert.assertEquals(cats.size(), 3);
|
||||
assertEquals(cats.size(), 3);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -13,13 +13,24 @@ import org.tests.model.basic.VehicleDriver;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestTextJsonInheritance extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test() throws IOException {
|
||||
public void parseJson_when_inheritanceType_outOfOrderDtype() {
|
||||
|
||||
String fom = "{\"id\":90,\"name\":\"Frank\",\"vehicle\":{\"id\":42,\"licenseNumber\":\"T100\",\"capacity\":99.0,\"dtype\":\"T\"}}";
|
||||
|
||||
VehicleDriver driver1 = Ebean.json().toBean(VehicleDriver.class, fom);
|
||||
assertThat(driver1.getVehicle()).isInstanceOf(Truck.class);
|
||||
assertThat(driver1.getVehicle().getLicenseNumber()).isEqualTo("T100");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
setupData();
|
||||
|
||||
|
||||
@@ -14,28 +14,8 @@ public class TestInsertManyAndRef extends BaseTestCase {
|
||||
@Test
|
||||
public void testMe() {
|
||||
|
||||
// ResetBasicData.reset();
|
||||
//
|
||||
// Customer u = new Customer();
|
||||
// u.setName("Mr Test");
|
||||
//
|
||||
// final List<Order> bookmarks = new ArrayList<Order>();
|
||||
// final Order b1 = new Order();
|
||||
// b1.setCustomer(u);
|
||||
// b1.setStatus(Status.NEW);
|
||||
//
|
||||
// final Order b2 = new Order();
|
||||
// b2.setStatus(Status.NEW);
|
||||
// b2.setCustomer(u);
|
||||
//
|
||||
// bookmarks.add(b1);
|
||||
// bookmarks.add(b2);
|
||||
//
|
||||
// Ebean.save(bookmarks);
|
||||
|
||||
final BBookmarkUser u = new BBookmarkUser();
|
||||
final BBookmarkUser u = new BBookmarkUser("Mr Test");
|
||||
u.setEmailAddress("test@test.com");
|
||||
u.setName("Mr Test");
|
||||
u.setPassword("password");
|
||||
|
||||
final List<BBookmark> bookmarks = new ArrayList<>();
|
||||
|
||||
Reference in New Issue
Block a user