001package io.ebeaninternal.server.query;
002
003import io.ebean.bean.EntityBean;
004import io.ebean.bean.EntityBeanIntercept;
005import io.ebeaninternal.api.SpiQuery.Mode;
006import io.ebeaninternal.server.deploy.BeanProperty;
007import io.ebeaninternal.server.deploy.DbReadContext;
008
009/**
010 * Controls the loading of property data into a bean.
011 * <p>
012 * Takes into account the differences of lazy loading and
013 * partial objects.
014 * </p>
015 */
016public class SqlBeanLoad {
017
018  private final DbReadContext ctx;
019  private final EntityBean bean;
020  private final EntityBeanIntercept ebi;
021
022  private final Class<?> type;
023  private final boolean lazyLoading;
024  private final boolean refreshLoading;
025  private final boolean rawSql;
026
027  SqlBeanLoad(DbReadContext ctx, Class<?> type, EntityBean bean, Mode queryMode) {
028
029    this.ctx = ctx;
030    this.rawSql = ctx.isRawSql();
031    this.type = type;
032    this.lazyLoading = queryMode == Mode.LAZYLOAD_BEAN;
033    this.refreshLoading = queryMode == Mode.REFRESH_BEAN;
034    this.bean = bean;
035    this.ebi = bean == null ? null : bean._ebean_getIntercept();
036  }
037
038  /**
039   * Return true if this is a lazy loading.
040   */
041  public boolean isLazyLoad() {
042    return lazyLoading;
043  }
044
045  /**
046   * Return the DB read context.
047   */
048  public DbReadContext ctx() {
049    return ctx;
050  }
051
052  public Object load(BeanProperty prop) {
053
054    if (!rawSql && !prop.isLoadProperty(ctx.isDraftQuery())) {
055      return null;
056    }
057
058    if ((bean == null)
059      || (lazyLoading && ebi.isLoadedProperty(prop.getPropertyIndex()))
060      || (type != null && !prop.isAssignableFrom(type))) {
061
062      // ignore this property
063      // ... null: bean already in persistence context
064      // ... lazyLoading: partial bean that is lazy loading
065      // ... type: inheritance and not assignable to this instance
066
067      prop.loadIgnore(ctx);
068      return null;
069    }
070
071    try {
072      Object dbVal = prop.read(ctx);
073      if (!refreshLoading) {
074        prop.setValue(bean, dbVal);
075      } else {
076        prop.setValueIntercept(bean, dbVal);
077      }
078
079      return dbVal;
080
081    } catch (Exception e) {
082      bean._ebean_getIntercept().setLoadError(prop.getPropertyIndex(), e);
083      ctx.handleLoadError(prop.getFullBeanName(), e);
084      return prop.getValue(bean);
085    }
086  }
087
088  /**
089   * Load the given value into the property.
090   */
091  public void load(BeanProperty target, Object dbVal) {
092    if (!refreshLoading) {
093      target.setValue(bean, dbVal);
094    } else {
095      target.setValueIntercept(bean, dbVal);
096    }
097  }
098}