mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1594 - Support loading of beans with invalid JSON content
Adjust to be per query via query.setAllowLoadErrors() rather than a global config via ServerConfig.
This commit is contained in:
@@ -372,6 +372,27 @@ public interface Query<T> {
|
||||
*/
|
||||
Query<T> setAutoTune(boolean autoTune);
|
||||
|
||||
/**
|
||||
* Execute the query allowing properties with invalid JSON to be collected and not fail the query.
|
||||
* <pre>{@code
|
||||
*
|
||||
* // fetch a bean with JSON content
|
||||
* EBasicJsonList bean= Ebean.find(EBasicJsonList.class)
|
||||
* .setId(42)
|
||||
* .setAllowLoadErrors() // collect errors into bean state if we have invalid JSON
|
||||
* .findOne();
|
||||
*
|
||||
*
|
||||
* // get the invalid JSON errors from the bean state
|
||||
* Map<String, Exception> errors = server().getBeanState(bean).getLoadErrors();
|
||||
*
|
||||
* // If this map is not empty tell we have invalid JSON
|
||||
* // and should try and fix the JSON content or inform the user
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
Query<T> setAllowLoadErrors();
|
||||
|
||||
/**
|
||||
* Set the default lazy loading batch size to use.
|
||||
* <p>
|
||||
|
||||
@@ -30,15 +30,9 @@ import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.meta.MetaInfoManager;
|
||||
import io.ebean.migration.MigrationRunner;
|
||||
import io.ebean.plugin.LoadErrorHandler;
|
||||
import io.ebean.util.StringHelper;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -527,10 +521,6 @@ public class ServerConfig {
|
||||
*/
|
||||
private boolean idGeneratorAutomatic = true;
|
||||
|
||||
private LoadErrorHandler loadErrorHandler = (bean, prop, fullName, e) -> {
|
||||
throw new PersistenceException("Error loading on " + fullName, e);
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a Server Configuration for programmatically creating an EbeanServer.
|
||||
*/
|
||||
@@ -3016,13 +3006,6 @@ public class ServerConfig {
|
||||
|
||||
String mappingsProp = p.get("mappingLocations", null);
|
||||
mappingLocations = getSearchList(mappingsProp, mappingLocations);
|
||||
|
||||
if (!p.getBoolean("failOnLoadError", true)) {
|
||||
Logger logger = LoggerFactory.getLogger("io.ebean.SQL");
|
||||
loadErrorHandler = (bean, prop, fullName, e) -> {
|
||||
logger.error("Error loading on {}", fullName, e);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private NamingConvention createNamingConvention(PropertiesWrapper properties, NamingConvention namingConvention) {
|
||||
@@ -3282,20 +3265,6 @@ public class ServerConfig {
|
||||
this.idGeneratorAutomatic = idGeneratorAutomatic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the load error handler.
|
||||
*/
|
||||
public LoadErrorHandler getLoadErrorHandler() {
|
||||
return loadErrorHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the loadErrorHandler.
|
||||
*/
|
||||
public void setLoadErrorHandler(LoadErrorHandler loadErrorHandler) {
|
||||
this.loadErrorHandler = loadErrorHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if query plan capture is enabled.
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,6 @@ import io.ebean.PersistenceContextScope;
|
||||
import io.ebean.ProfileLocation;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.bean.CallStack;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.event.readaudit.ReadEvent;
|
||||
@@ -16,7 +15,6 @@ import io.ebean.plugin.BeanType;
|
||||
import io.ebeaninternal.server.autotune.ProfilingListener;
|
||||
import io.ebeaninternal.server.core.SpiOrmQueryRequest;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.deploy.TableJoin;
|
||||
import io.ebeaninternal.server.query.CancelableQuery;
|
||||
@@ -855,5 +853,5 @@ public interface SpiQuery<T> extends Query<T>, TxnProfileEventCodes {
|
||||
/**
|
||||
* Handles load errors.
|
||||
*/
|
||||
void handleLoadError(EntityBean bean, BeanProperty prop, String fullName, Exception e);
|
||||
void handleLoadError(String fullName, Exception e);
|
||||
}
|
||||
|
||||
@@ -94,6 +94,6 @@ public interface DbReadContext {
|
||||
/**
|
||||
* Handles a load error on given property.
|
||||
*/
|
||||
void handleLoadError(EntityBean bean, BeanProperty prop, String fullName, Exception e);
|
||||
void handleLoadError(String fullName, Exception e);
|
||||
|
||||
}
|
||||
|
||||
@@ -52,9 +52,8 @@ class DynamicPropertyAggregationFormula extends DynamicPropertyBase {
|
||||
Object value;
|
||||
try {
|
||||
value = scalarType.read(sqlBeanLoad.ctx().getDataReader());
|
||||
|
||||
} catch (Exception e) {
|
||||
sqlBeanLoad.ctx().handleLoadError(null, asTarget, fullName, e);
|
||||
sqlBeanLoad.ctx().handleLoadError(fullName, e);
|
||||
return;
|
||||
}
|
||||
if (asTarget != null) {
|
||||
|
||||
@@ -21,7 +21,6 @@ import io.ebeaninternal.server.core.SpiOrmQueryRequest;
|
||||
import io.ebeaninternal.server.deploy.BeanCollectionHelp;
|
||||
import io.ebeaninternal.server.deploy.BeanCollectionHelpFactory;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
||||
import io.ebeaninternal.server.type.DataBind;
|
||||
@@ -817,8 +816,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLoadError(EntityBean bean, BeanProperty prop, String fullName, Exception e) {
|
||||
query.handleLoadError(bean, prop, fullName, e);
|
||||
public void handleLoadError(String fullName, Exception e) {
|
||||
query.handleLoadError(fullName, e);
|
||||
}
|
||||
|
||||
public Set<String> getDependentTables() {
|
||||
|
||||
@@ -87,7 +87,7 @@ public class SqlBeanLoad {
|
||||
|
||||
} catch (Exception e) {
|
||||
bean._ebean_getIntercept().setLoadError(prop.getPropertyIndex(), e);
|
||||
ctx.handleLoadError(bean, prop, prop.getFullBeanName(), e);
|
||||
ctx.handleLoadError(prop.getFullBeanName(), e);
|
||||
return prop.getValue(bean);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import io.ebean.Transaction;
|
||||
import io.ebean.UpdateQuery;
|
||||
import io.ebean.Version;
|
||||
import io.ebean.bean.CallStack;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.bean.ObjectGraphOrigin;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
@@ -47,7 +46,6 @@ import io.ebeaninternal.api.SpiQuerySecondary;
|
||||
import io.ebeaninternal.server.autotune.ProfilingListener;
|
||||
import io.ebeaninternal.server.core.SpiOrmQueryRequest;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.deploy.InheritInfo;
|
||||
import io.ebeaninternal.server.deploy.TableJoin;
|
||||
@@ -57,6 +55,7 @@ import io.ebeaninternal.server.query.CancelableQuery;
|
||||
import io.ebeaninternal.server.query.NativeSqlQueryPlanKey;
|
||||
import io.ebeaninternal.server.rawsql.SpiRawSql;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -141,6 +140,8 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
|
||||
private String lazyLoadManyPath;
|
||||
|
||||
private boolean allowLoadErrors;
|
||||
|
||||
/**
|
||||
* Flag set for report/DTO beans when we may choose to explicitly include the Id property.
|
||||
*/
|
||||
@@ -329,8 +330,10 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
@Override
|
||||
public String profileEventId() {
|
||||
switch (mode) {
|
||||
case LAZYLOAD_BEAN: return FIND_ONE_LAZY;
|
||||
case LAZYLOAD_MANY: return FIND_MANY_LAZY;
|
||||
case LAZYLOAD_BEAN:
|
||||
return FIND_ONE_LAZY;
|
||||
case LAZYLOAD_MANY:
|
||||
return FIND_MANY_LAZY;
|
||||
default:
|
||||
return type.profileEventId();
|
||||
}
|
||||
@@ -343,7 +346,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
|
||||
@Override
|
||||
public Query<T> setProfileId(int profileId) {
|
||||
this.profileId = (short)profileId;
|
||||
this.profileId = (short) profileId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -409,6 +412,12 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
this.asOfBaseTable = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultOrmQuery<T> setAllowLoadErrors() {
|
||||
this.allowLoadErrors = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementAsOfTableCount() {
|
||||
asOfTableCount++;
|
||||
@@ -463,7 +472,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
|
||||
@Override
|
||||
public DefaultOrmQuery<T> setRawSql(RawSql rawSql) {
|
||||
this.rawSql = (SpiRawSql)rawSql;
|
||||
this.rawSql = (SpiRawSql) rawSql;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -775,6 +784,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
copy.baseTable = baseTable;
|
||||
copy.rootTableAlias = rootTableAlias;
|
||||
copy.distinct = distinct;
|
||||
copy.allowLoadErrors = allowLoadErrors;
|
||||
copy.timeout = timeout;
|
||||
copy.mapKey = mapKey;
|
||||
copy.id = id;
|
||||
@@ -1088,6 +1098,9 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
if (distinct) {
|
||||
sb.append(",dist:");
|
||||
}
|
||||
if (allowLoadErrors) {
|
||||
sb.append(",allowLoadErrors:");
|
||||
}
|
||||
if (disableLazyLoading) {
|
||||
sb.append(",disLazy:");
|
||||
}
|
||||
@@ -1194,6 +1207,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
beanDescriptor.appendOrderById(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate a hash based on the bind values used in the query.
|
||||
* <p>
|
||||
@@ -1278,7 +1292,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
|
||||
@Override
|
||||
public boolean isBeanCacheGet() {
|
||||
return useBeanCache.isGet() && beanDescriptor.isBeanCaching() ;
|
||||
return useBeanCache.isGet() && beanDescriptor.isBeanCaching();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1337,7 +1351,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
|
||||
@Override
|
||||
public DefaultOrmQuery<T> select(FetchGroup fetchGroup) {
|
||||
this.detail = ((SpiFetchGroup)fetchGroup).detail();
|
||||
this.detail = ((SpiFetchGroup) fetchGroup).detail();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1969,8 +1983,10 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLoadError(EntityBean bean, BeanProperty prop, String fullName, Exception e) {
|
||||
server.getServerConfig().getLoadErrorHandler().handleLoadError(bean, prop, fullName, e);
|
||||
public void handleLoadError(String fullName, Exception e) {
|
||||
if (!allowLoadErrors) {
|
||||
throw new PersistenceException("Error loading on " + fullName, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user