Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Copyright 2014-2015 the original author or authors.
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
   * either express or implied. See the License for the specific language
   * governing permissions and limitations under the License.
   */
  package org.dbflute.bhv;
  
  import java.util.Date;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
The abstract class of readable behavior.

Parameters:
<ENTITY> The type of entity handled by this behavior.
<CB> The type of condition-bean handled by this behavior.
Author(s):
jflute
 
 public abstract class AbstractBehaviorReadable<ENTITY extends Entity, CB extends ConditionBeanimplements BehaviorReadable {
 
     // ===================================================================================
     //                                                                          Definition
     //                                                                          ==========
     
The prefix mark for derived mapping alias.
 
     protected static final String DERIVED_MAPPABLE_ALIAS_PREFIX = .;

    
The empty instance for provider of list handling for nested referrer. (wild-card generic for downcast)
 
     protected static final NestedReferrerListGateway<?> EMPTY_NREF_LGWAY = new NestedReferrerListGateway<Entity>() {
         public void withNestedReferrer(ReferrerListHandler<Entityhandler) {
             final List<EntityemptyList = DfCollectionUtil.emptyList();
             handler.handle(emptyList);
         }
     };
 
     // ===================================================================================
     //                                                                           Attribute
     //                                                                           =========
     
Behavior-selector instance. It's basically referred at loadReferrer. (Required for loadReferrer)
 
     protected BehaviorCommandInvoker _behaviorCommandInvoker;

    
Behavior-selector instance. It's basically referred at loadReferrer. (Required for loadReferrer)
 
     protected BehaviorSelector _behaviorSelector;
 
     // ===================================================================================
     //                                                                          Table name
     //                                                                          ==========
     
 
     @SuppressWarnings("unchecked")
     public ENTITY newEntity() {
         return (ENTITY) asDBMeta().newEntity();
     }
 
     protected CB createCB(CBCall<CB> cbCall) { // CB from callback
         assertCBCallNotNull(cbCall);
         final CB cb = newConditionBean();
         cbCall.callback(cb);
         return cb;
     }

    
 
     public abstract CB newConditionBean(); // defined here to resolve generic of return type
 
     // ===================================================================================
     //                                                                        Count Select
     //                                                                        ============
     // -----------------------------------------------------
     //                                         Main Entrance
     //                                         -------------
     protected int facadeSelectCount(CB cb) {
         return doSelectCountUniquely(cb);
     }
 
     protected int doSelectCountUniquely(CB cb) { // called by selectCount(cb)
         assertCBStateValid(cb);
         return delegateSelectCountUniquely(cb);
     }
 
     protected int doSelectCountPlainly(CB cb) { // called by selectPage(cb)
         assertCBStateValid(cb);
         return delegateSelectCountPlainly(cb);
     }
 
     // -----------------------------------------------------
     //                                    Interface Dispatch
     //                                    ------------------
     
 
     public int readCount(ConditionBean cb) {
         assertCBStateValid(cb);
         return doReadCount(cb);
     }
 
     protected int doReadCount(ConditionBean cb) {
         return facadeSelectCount(downcast(cb));
     }
 
     // ===================================================================================
     //                                                                       Entity Select
     //                                                                       =============
     // -----------------------------------------------------
     //                                         Main Entrance
     //                                         -------------
     // *several methods cannot be resolved because they are changed by generator option
     protected <RESULT extends ENTITY> RESULT doSelectEntity(CB cbClass<? extends RESULT> entityType) {
         return helpSelectEntityInternally(cbentityType);
     }
 
     protected ENTITY facadeSelectEntityWithDeletedCheck(CB cb) {
         return doSelectEntityWithDeletedCheck(cbtypeOfSelectedEntity());
     }
 
     protected <RESULT extends ENTITY> RESULT doSelectEntityWithDeletedCheck(CB cbClass<? extends RESULT> entityType) {
         assertCBStateValid(cb);
         assertObjectNotNull("entityType"entityType);
         return helpSelectEntityWithDeletedCheckInternally(cbentityType);
     }
 
     // -----------------------------------------------------
     //                                       Internal Helper
     //                                       ---------------
     protected <RESULT extends ENTITY> RESULT helpSelectEntityInternally(CB cbClass<? extends RESULT> entityType) {
         assertConditionBeanSelectResource(cbentityType);
         if (cb.hasSelectAllPossible() && cb.getFetchSize() != 1) { // if no condition for one
             throwSelectEntityConditionNotFoundException(cb);
         }
         final int preSafetyMaxResultSize = xcheckSafetyResultAsOne(cb);
         final List<RESULT> ls;
         try {
             ls = delegateSelectList(cbentityType);
         } catch (FetchingOverSafetySizeException e) {
             throwSelectEntityDuplicatedException("{over safetyMaxResultSize '1'}"cbe);
             return null// unreachable
         } finally {
             xrestoreSafetyResult(cbpreSafetyMaxResultSize);
         }
         if (ls.isEmpty()) {
             return null;
         }
         assertEntitySelectedAsOne(lscb);
         return (RESULT) ls.get(0);
     }
 
     protected <RESULT extends ENTITY> RESULT helpSelectEntityWithDeletedCheckInternally(CB cbClass<? extends RESULT> entityType) {
         final RESULT entity = helpSelectEntityInternally(cbentityType);
         assertEntityNotDeleted(entitycb);
         return entity;
     }
 
     protected int xcheckSafetyResultAsOne(ConditionBean cb) {
         final int safetyMaxResultSize = cb.getSafetyMaxResultSize();
         cb.checkSafetyResult(1);
         return safetyMaxResultSize;
     }
 
     protected void xrestoreSafetyResult(ConditionBean cbint preSafetyMaxResultSize) {
         cb.checkSafetyResult(preSafetyMaxResultSize);
     }
 
     // -----------------------------------------------------
     //                                       Result Handling
     //                                       ---------------
     
Assert that the entity is not deleted.

Parameters:
entity Selected entity. (NullAllowed)
searchKey Search-key for logging.
Throws:
org.dbflute.exception.EntityAlreadyDeletedException When the entity has already been deleted.
 
     protected void assertEntityNotDeleted(Entity entityObject searchKey) {
         if (entity == null) {
             throwSelectEntityAlreadyDeletedException(searchKey);
         }
     }

    
Assert that the entity is not deleted.

Parameters:
ls Selected list. (NullAllowed)
searchKey Search-key for logging. (NotNull)
Throws:
org.dbflute.exception.EntityAlreadyDeletedException When the entity has already been deleted. (not found)
 
     protected void assertEntityNotDeleted(List<? extends EntitylsObject searchKey) {
         if (ls == null || ls.isEmpty()) {
             throwSelectEntityAlreadyDeletedException(searchKey);
         }
     }

    
Assert that the entity is selected as one.

Parameters:
ls Selected list. (NotNull)
searchKey Search-key for logging. (NotNull)
Throws:
org.dbflute.exception.EntityAlreadyDeletedException When the entity has already been deleted. (not found)
org.dbflute.exception.EntityDuplicatedException When the entity has been duplicated.
 
     protected void assertEntitySelectedAsOne(List<? extends EntitylsObject searchKey) {
         if (ls == null || ls.isEmpty()) {
             throwSelectEntityAlreadyDeletedException(searchKey);
         }
         if (ls.size() > 1) {
             throwSelectEntityDuplicatedException(String.valueOf(ls.size()), searchKeynull);
         }
     }
 
     protected void throwSelectEntityAlreadyDeletedException(Object searchKey) {
     }
 
     protected void throwSelectEntityDuplicatedException(String resultCountExpObject searchKeyThrowable cause) {
         createBhvExThrower().throwSelectEntityDuplicatedException(resultCountExpsearchKeycause);
     }
 
     }
 
     // -----------------------------------------------------
     //                                    Interface Dispatch
     //                                    ------------------
     
 
     public Entity readEntity(ConditionBean cb) {
         assertCBStateValid(cb);
         return doReadEntity(cb);
     }
 
     protected abstract Entity doReadEntity(ConditionBean cb);
 
     protected <RESULT> OptionalEntity<RESULT> createOptionalEntity(RESULT entityfinal Object... searchKey) {
         return new OptionalEntity<RESULT>(entitynew OptionalThingExceptionThrower() {
             public void throwNotFoundException() {
                 throwSelectEntityAlreadyDeletedException(searchKey);
             }
         });
     }

    
 
         assertCBStateValid(cb);
         return doReadEntityWithDeletedCheck(cb);
     }
 
         return facadeSelectEntityWithDeletedCheck(downcast(cb));
     }
 
     // ===================================================================================
     //                                                                         List Select
     //                                                                         ===========
     // -----------------------------------------------------
     //                                         Main Entrance
     //                                         -------------
     protected ListResultBean<ENTITY> facadeSelectList(CB cb) {
         return doSelectList(cbtypeOfSelectedEntity());
     }
 
     protected <RESULT extends ENTITY> ListResultBean<RESULT> doSelectList(CB cbClass<? extends RESULT> entityType) {
         return helpSelectListInternally(cbentityType);
     }
 
     // -----------------------------------------------------
     //                                       Internal Helper
     //                                       ---------------
     protected <RESULT extends ENTITY> ListResultBean<RESULT> helpSelectListInternally(CB cbClass<? extends RESULT> entityType) {
         assertConditionBeanSelectResource(cbentityType);
         try {
             final List<RESULT> selectedList = delegateSelectList(cbentityType);
             return createListResultBean(cbselectedList);
         } catch (FetchingOverSafetySizeException e) {
             createBhvExThrower().throwDangerousResultSizeException(cbe);
             return null// unreachable
         }
     }
 
     protected <RESULT extends EntityListResultBean<RESULT> createListResultBean(ConditionBean cbList<RESULT> selectedList) {
         return new ResultBeanBuilder<RESULT>(asTableDbName()).buildListOfCB(cbselectedList);
     }
 
     // -----------------------------------------------------
     //                                       Option Handling
     //                                       ---------------
     protected boolean isEntityDerivedMappable() {
         return false// depends on generator
     }
 
     protected void throwSpecifyDerivedReferrerEntityPropertyNotFoundException(String aliasClass<?> entityType) {
     }
 
     // -----------------------------------------------------
     //                                    Interface Dispatch
     //                                    ------------------
     
 
     public <RESULT extends EntityListResultBean<RESULT> readList(ConditionBean cb) {
         assertCBStateValid(cb);
         @SuppressWarnings("unchecked")
         final ListResultBean<RESULT> entityList = (ListResultBean<RESULT>) doReadList(cb);
         return entityList;
     }
 
     protected ListResultBean<? extends EntitydoReadList(ConditionBean cb) {
         return facadeSelectList(downcast(cb));
     }
 
     // ===================================================================================
     //                                                                         Page Select
     //                                                                         ===========
     // -----------------------------------------------------
     //                                         Main Entrance
     //                                         -------------
     protected PagingResultBean<ENTITY> facadeSelectPage(CB cb) {
         return doSelectPage(cbtypeOfSelectedEntity());
     }
 
     protected <RESULT extends ENTITY> PagingResultBean<RESULT> doSelectPage(CB cbClass<? extends RESULT> entityType) {
         return helpSelectPageInternally(cbentityType);
     }
 
     protected <RESULT extends ENTITY> PagingResultBean<RESULT> helpSelectPageInternally(CB cbClass<? extends RESULT> entityType) {
         assertConditionBeanSelectResource(cbentityType);
         try {
             final PagingHandler<RESULT> handler = createPagingHandler(cbentityType);
             final PagingInvoker<RESULT> invoker = createPagingInvoker(cb);
             return invoker.invokePaging(handler);
         } catch (PagingOverSafetySizeException e) {
             createBhvExThrower().throwDangerousResultSizeException(cbe);
             return null// unreachable
         }
     }
 
     protected <RESULT extends ENTITY> PagingHandler<RESULT> createPagingHandler(final CB cbfinal Class<? extends RESULT> entityType) {
         return new PagingHandler<RESULT>() {
             public PagingBean getPagingBean() {
                 return cb;
             }
 
             public int count() {
                 try {
                     cb.getSqlClause().enablePagingAdjustment();
                     return delegateSelectCountPlainly(cb);
                 } finally {
                     cb.getSqlClause().disablePagingAdjustment();
                 }
             }
 
             public List<RESULT> paging() {
                 try {
                     cb.getSqlClause().enablePagingAdjustment();
                     return delegateSelectList(cbentityType);
                 } finally {
                     cb.getSqlClause().disablePagingAdjustment();
                 }
             }
         };
     }
 
     protected <RESULT extends ENTITY> PagingInvoker<RESULT> createPagingInvoker(CB cb) {
         return cb.createPagingInvoker(asTableDbName());
     }
 
     // -----------------------------------------------------
     //                                    Interface Dispatch
     //                                    ------------------
     
 
     public <RESULT extends EntityPagingResultBean<RESULT> readPage(final ConditionBean cb) {
         assertCBStateValid(cb);
         @SuppressWarnings("unchecked")
         final PagingResultBean<RESULT> entityList = (PagingResultBean<RESULT>) doReadPage(cb);
         return entityList;
     }
 
     protected PagingResultBean<? extends EntitydoReadPage(ConditionBean cb) {
         return facadeSelectPage(downcast(cb));
     }
 
     // ===================================================================================
     //                                                                       Cursor Select
     //                                                                       =============
     // -----------------------------------------------------
     //                                         Main Entrance
     //                                         -------------
     protected void facadeSelectCursor(CB cbEntityRowHandler<ENTITY> entityRowHandler) {
         doSelectCursor(cbentityRowHandlertypeOfSelectedEntity());
     }
 
     protected <RESULT extends ENTITY> void doSelectCursor(CB cbEntityRowHandler<RESULT> handlerClass<? extends RESULT> entityType) {
         assertCBStateValid(cb);
         assertObjectNotNull("entityRowHandler"handler);
         assertObjectNotNull("entityType"entityType);
         assertSpecifyDerivedReferrerEntityProperty(cbentityType);
         helpSelectCursorInternally(cbhandlerentityType);
     }
 
     // -----------------------------------------------------
     //                                       Internal Helper
     //                                       ---------------
     protected <RESULT extends ENTITY> void helpSelectCursorInternally(CB cbEntityRowHandler<RESULT> handler,
             Class<? extends RESULT> entityType) {
         assertObjectNotNull("entityRowHandler"handler);
         assertConditionBeanSelectResource(cbentityType);
         final CursorSelectOption option = cb.getCursorSelectOption();
         if (option != null && option.isByPaging()) {
             helpSelectCursorHandlingByPaging(cbhandlerentityTypeoption);
         } else { // basically here
             delegateSelectCursor(cbhandlerentityType);
         }
     }
 
     protected <RESULT extends ENTITY> void helpSelectCursorHandlingByPaging(CB cbEntityRowHandler<RESULT> entityRowHandler,
             Class<? extends RESULT> entityTypeCursorSelectOption option) {
         helpSelectCursorCheckingByPagingAllowed(cboption);
         helpSelectCursorCheckingOrderByPK(cboption);
         final int pageSize = option.getPageSize();
         int pageNumber = 1;
         while (true) {
             cb.paging(pageSizepageNumber);
             List<RESULT> pageList = delegateSelectList(cbentityType);
             for (RESULT entity : pageList) {
                 entityRowHandler.handle(entity);
             }
             if (pageList.size() < pageSize) { // means last page
                 break;
             }
             ++pageNumber;
         }
     }
 
     protected void helpSelectCursorCheckingByPagingAllowed(CB cbCursorSelectOption option) {
         if (!cb.getSqlClause().isCursorSelectByPagingAllowed()) {
             String msg = "The cursor select by paging is not allowed at the DBMS.";
             throw new IllegalConditionBeanOperationException(msg);
         }
     }
 
     protected void helpSelectCursorCheckingOrderByPK(CB cbCursorSelectOption option) {
         if (option.isOrderByPK()) {
             final OrderByClause orderByClause = cb.getOrderByComponent();
             final OrderByElement orderByFirstElement = orderByClause.getOrderByFirstElement();
             if (orderByFirstElement == null || !orderByFirstElement.getColumnInfo().isPrimary()) {
                 String msg = "The cursor select by paging needs order by primary key: " + cb.asTableDbName();
                 throw new IllegalConditionBeanOperationException(msg);
             }
         }
     }
 
     // -----------------------------------------------------
     //                                    Interface Dispatch
     //                                    ------------------
     @SuppressWarnings("unchecked")
     public <RESULT extends Entityvoid readCursor(ConditionBean cbEntityRowHandler<RESULT> entityLambda) {
         facadeSelectCursor(downcast(cb), (EntityRowHandler<ENTITY>) entityLambda);
     }
 
     // ===================================================================================
     //                                                                       Scalar Select
     //                                                                       =============
     // -----------------------------------------------------
     //                                         Main Entrance
     //                                         -------------
     // internal name is ScalarSelect
     protected <RESULT> HpSLSFunction<CB, RESULT> facadeScalarSelect(Class<RESULT> resultType) {
         return doScalarSelect(resultTypenewConditionBean());
     }
 
     protected <RESULT> HpSLSFunction<CB, RESULT> doScalarSelect(final Class<RESULT> resultTypefinal CB cb) {
         assertObjectNotNull("resultType"resultType);
         assertCBStateValid(cb);
         cb.xsetupForScalarSelect();
         cb.getSqlClause().disableSelectIndex(); // for when you use union
         HpSLSExecutor<CB, RESULT> executor = createHpSLSExecutor(); // variable to resolve generic
         return createSLSFunction(cbresultTypeexecutor);
     }
 
     protected <RESULT> HpSLSExecutor<CB, RESULT> createHpSLSExecutor() {
         return new HpSLSExecutor<CB, RESULT>() {
             public RESULT execute(CB cbClass<RESULT> resultTypeSelectClauseType selectClauseType) {
                 return invoke(createSelectScalarCBCommand(cbresultTypeselectClauseType));
             }
         };
     }
 
     protected <RESULT> HpSLSFunction<CB, RESULT> createSLSFunction(CB cbClass<RESULT> resultTypeHpSLSExecutor<CB, RESULT> exec) {
         return newSLSFunction(cbresultTypeexec);
     }
 
     protected <RESULT> HpSLSFunction<CB, RESULT> newSLSFunction(CB cbClass<RESULT> resultTypeHpSLSExecutor<CB, RESULT> exec) {
         return new HpSLSFunction<CB, RESULT>(cbresultTypeexec);
     }
 
     protected <RESULT> HpSLSFunction<? extends ConditionBean, RESULT> doReadScalar(Class<RESULT> resultTYpe) {
         return facadeScalarSelect(resultTYpe);
     }
 
     // -----------------------------------------------------
     //                                    Interface Dispatch
     //                                    ------------------
     
 
     public <RESULT> HpSLSFunction<ConditionBean, RESULT> readScalar(Class<RESULT> resultType) {
         @SuppressWarnings("unchecked")
         final HpSLSFunction<ConditionBean, RESULT> func = (HpSLSFunction<ConditionBean, RESULT>) doReadScalar(resultType);
         return func;
     }
 
     // ===================================================================================
     //                                                                          OutsideSql
     //                                                                          ==========
     
 
     public <BEHAVIOR extends BehaviorReadableOutsideSqlAllFacadeExecutor<BEHAVIOR> readyOutsideSql() {
         return doOutsideSql();
     }

    
Prepare an outside-SQL execution by returning an instance of the executor for outside-SQL.
It's an extension point for your adding original customization to outside-SQL executions.

Parameters:
<BEHAVIOR> The type of behavior.
Returns:
The facade for outside-SQL. (NotNull)
 
     protected <BEHAVIOR extends BehaviorReadableOutsideSqlAllFacadeExecutor<BEHAVIOR> doOutsideSql() {
         assertBehaviorCommandInvoker("outsideSql");
     }
 
     // ===================================================================================
     //                                                                            Sequence
     //                                                                            ========
     
 
     public Number readNextVal() {
         return doReadNextVal();
     }
 
     protected abstract Number doReadNextVal();
 
     // ===================================================================================
     //                                                                       Load Referrer
     //                                                                       =============
     // -----------------------------------------------------
     //                                       New Entry Point
     //                                       ---------------
     
Help load referrer internally. (new entry point)
About internal policy, the value of primary key(and others too) is treated as CaseInsensitive.

Parameters:
<LOCAL_ENTITY> The type of base entity.
<PK> The type of primary key.
<REFERRER_CB> The type of referrer condition-bean.
<REFERRER_ENTITY> The type of referrer entity.
localEntityList The list of local entity. (NotNull)
loadReferrerOption The option of loadReferrer. (NotNull)
referrerProperty The property name of referrer. (NotNull)
Returns:
The callback to load nested referrer. (NotNull)
 
     protected <LOCAL_ENTITY extends Entity, PK, REFERRER_CB extends ConditionBean, REFERRER_ENTITY extends Entity// generic
     NestedReferrerListGateway<REFERRER_ENTITY> helpLoadReferrerInternally(List<LOCAL_ENTITY> localEntityList,
             LoadReferrerOption<REFERRER_CB, REFERRER_ENTITY> loadReferrerOptionString referrerProperty) {
         return doHelpLoadReferrerInternally(localEntityListloadReferrerOptionreferrerProperty);
     }
 
     protected <LOCAL_ENTITY extends Entity, KEY, REFERRER_CB extends ConditionBean, REFERRER_ENTITY extends Entity// generic
     NestedReferrerListGateway<REFERRER_ENTITY> doHelpLoadReferrerInternally(List<LOCAL_ENTITY> localEntityList,
             LoadReferrerOption<REFERRER_CB, REFERRER_ENTITY> loadReferrerOptionfinal String referrerProperty) {
         final DBMeta dbmeta = asDBMeta();
         final ReferrerInfo referrerInfo = dbmeta.findReferrerInfo(referrerProperty);
         final BehaviorReadable referrerBhv = xfindReferrerBehavior(referrerInfo);
         final Set<ColumnInfopkColSet = referrerInfo.getLocalReferrerColumnInfoMap().keySet(); // might be unique key
         final Map<ColumnInfoColumnInfomappingColMap = referrerInfo.getReferrerLocalColumnInfoMap(); // key is referrer's
         final InternalLoadReferrerCallback<LOCAL_ENTITY, KEY, REFERRER_CB, REFERRER_ENTITY> callback;
         if (pkColSet.size() == 1) { // simple key
             final ColumnInfo pkCol = pkColSet.iterator().next();
             final ColumnInfo fkCol = mappingColMap.keySet().iterator().next();
             callback = xcreateLoadReferrerCallback(referrerPropertydbmetareferrerInforeferrerBhvpkColfkCol);
         } else { // compound key
             final Set<ColumnInfofkColSet = mappingColMap.keySet();
             callback = xcreateLoadReferrerCallback(referrerPropertydbmetareferrerInforeferrerBhvpkColSetfkColSetmappingColMap);
         }
         return helpLoadReferrerInternally(localEntityListloadReferrerOptioncallback);
     }
 
     protected BehaviorReadable xfindReferrerBehavior(final ReferrerInfo referrerInfo) {
         final String behaviorName = referrerInfo.getReferrerDBMeta().getBehaviorTypeName();
         @SuppressWarnings("unchecked")
         final Class<BehaviorReadablebehaviorType = (Class<BehaviorReadable>) DfReflectionUtil.forName(behaviorName);
         return xgetBSFLR().select(behaviorType);
     }
 
     // -----------------------------------------------------
     //                                      Loading Callback
     //                                      ----------------
     protected <LOCAL_ENTITY extends Entity, KEY, REFERRER_CB extends ConditionBean, REFERRER_ENTITY extends Entity// generic
     InternalLoadReferrerCallback<LOCAL_ENTITY, KEY, REFERRER_CB, REFERRER_ENTITY> // return
     xcreateLoadReferrerCallback(final String referrerPropertyfinal DBMeta dbmetafinal ReferrerInfo referrerInfo,
             final BehaviorReadable referrerBhvfinal ColumnInfo pkColfinal ColumnInfo fkCol) {
         return new InternalLoadReferrerCallback<LOCAL_ENTITY, KEY, REFERRER_CB, REFERRER_ENTITY>() { // for simple key
             public KEY getPKVal(LOCAL_ENTITY entity) {
                 return pkCol.read(entity); // (basically) PK cannot be optional because of not-null
             }
 
             public void setRfLs(LOCAL_ENTITY entityList<REFERRER_ENTITY> referrerList) {
                 referrerInfo.write(entityreferrerList);
             }
 
             @SuppressWarnings("unchecked")
             public REFERRER_CB newMyCB() {
                 return (REFERRER_CB) referrerBhv.newConditionBean();
             }
 
             public void qyFKIn(REFERRER_CB cbCollection<KEY> pkList) {
                 final String conditionKey = ..getConditionKey();
                 cb.localCQ().invokeQuery(fkCol.getColumnDbName(), conditionKeypkList);
             }
 
             public void qyOdFKAsc(REFERRER_CB cb) {
                 cb.localCQ().invokeOrderBy(fkCol.getColumnDbName(), true);
             }
 
             public void spFKCol(REFERRER_CB cb) {
                 cb.localSp().xspecifyColumn(fkCol.getColumnDbName());
             }
 
             public List<REFERRER_ENTITY> selRfLs(REFERRER_CB cb) {
                 return referrerBhv.readList(cb);
             }
 
             public KEY getFKVal(REFERRER_ENTITY entity) {
                 final Class<?> fkType = fkCol.getObjectNativeType();
                 final Class<?> pkType = pkCol.getObjectNativeType();
                 final Object fkValue = fkCol.read(entity);
                 return xconvertFK2PKImplicitly(referrerPropertyfkTypepkTypefkValue);
             }
 
             public void setlcEt(REFERRER_ENTITY referrerEntity, LOCAL_ENTITY localEntity) {
                 final RelationInfo reverseInfo = referrerInfo.getReverseRelation();
                 final Object written = xconvertToRelationOptionalEntityIfNeeds(localEntityreverseInfo);
                 reverseInfo.write(referrerEntitywritten);
             }
 
             public String getRfPrNm() {
                 return referrerProperty;
             }
         };
     }
 
     protected <LOCAL_ENTITY extends Entity, KEY, REFERRER_CB extends ConditionBean, REFERRER_ENTITY extends Entity// generic
     InternalLoadReferrerCallback<LOCAL_ENTITY, KEY, REFERRER_CB, REFERRER_ENTITY> // return
     xcreateLoadReferrerCallback(final String referrerPropertyfinal DBMeta dbmetafinal ReferrerInfo referrerInfo,
             final BehaviorReadable referrerBhvfinal Set<ColumnInfopkColSetfinal Set<ColumnInfofkColSet,
             final Map<ColumnInfoColumnInfomappingColMap) {
         return new InternalLoadReferrerCallback<LOCAL_ENTITY, KEY, REFERRER_CB, REFERRER_ENTITY>() { // for compound key
             @SuppressWarnings("unchecked")
             public KEY getPKVal(LOCAL_ENTITY entity) {
                 final Map<StringObjectkeyMap = xnewLoadReferrerCompoundKeyMap();
                 for (ColumnInfo pkCol : pkColSet) {
                     keyMap.put(pkCol.getColumnDbName(), pkCol.read(entity)); // key is DB name
                 }
                 return (KEY) keyMap;
                 // cannot use because it might be unique key
                 //return (KEY) dbmeta.extractPrimaryKeyMap(entity);
             }
 
             public void setRfLs(LOCAL_ENTITY entityList<REFERRER_ENTITY> referrerList) {
                 referrerInfo.write(entityreferrerList);
             }
 
             @SuppressWarnings("unchecked")
             public REFERRER_CB newMyCB() {
                 return (REFERRER_CB) referrerBhv.newConditionBean();
             }
 
             public void qyFKIn(REFERRER_CB cbfinal Collection<KEY> pkList) {
                 // compound key doesn't use InScope so OrScopeQuery 
                 cb.invokeOrScopeQuery(new OrQuery<ConditionBean>() {
                     public void query(ConditionBean orCB) {
                         for (final KEY pkKey : pkList) {
                             @SuppressWarnings("unchecked")
                             final Map<StringObjectpkMap = (Map<StringObject>) pkKey;
                             orCB.invokeOrScopeQueryAndPart(new AndQuery<ConditionBean>() {
                                 public void query(ConditionBean andCB) {
                                     for (ColumnInfo fkCol : fkColSet) {
                                         final ColumnInfo pkCol = mappingColMap.get(fkCol);
                                         final Object pkValue = pkMap.get(pkCol.getColumnDbName()); // key is DB name
                                         andCB.localCQ().invokeQueryEqual(fkCol.getColumnDbName(), pkValue);
                                     }
                                 }
                             });
                         }
                     }
                 });
             }
 
             public void qyOdFKAsc(REFERRER_CB cb) {
                 for (ColumnInfo fkCol : fkColSet) {
                     cb.localCQ().invokeOrderBy(fkCol.getColumnDbName(), true);
                 }
             }
 
             public void spFKCol(REFERRER_CB cb) {
                 for (ColumnInfo fkCol : fkColSet) {
                     cb.localSp().xspecifyColumn(fkCol.getColumnDbName());
                 }
             }
 
             public List<REFERRER_ENTITY> selRfLs(REFERRER_CB cb) {
                 return referrerBhv.readList(cb);
             }
 
             @SuppressWarnings("unchecked")
             public KEY getFKVal(REFERRER_ENTITY entity) {
                 final Map<StringObjectfkMap = xnewLoadReferrerCompoundKeyMap();
                 for (ColumnInfo fkCol : fkColSet) {
                     final Object fkValue = fkCol.read(entity);
                     final ColumnInfo pkCol = mappingColMap.get(fkCol);
                     final String mapKey = pkCol.getColumnDbName(); // key is DB name
                     final Class<?> fkType = fkCol.getObjectNativeType();
                     final Class<?> pkType = pkCol.getObjectNativeType();
                     final Object realValue;
                     if (fkType.equals(pkType)) { // basically true
                         realValue = fkValue;
                     } else { // different type (needs implicit conversion)
                         realValue = xconvertFK2PKImplicitly(referrerPropertyfkTypepkTypefkValue);
                     }
                     fkMap.put(mapKeyrealValue);
                 }
                 return (KEY) fkMap;
             }
 
             public void setlcEt(REFERRER_ENTITY referrerEntity, LOCAL_ENTITY localEntity) {
                 final RelationInfo reverseInfo = referrerInfo.getReverseRelation(); // always exists
                 final Object written = xconvertToRelationOptionalEntityIfNeeds(localEntityreverseInfo);
                 reverseInfo.write(referrerEntitywritten);
             }
 
             public String getRfPrNm() {
                 return referrerProperty;
             }
         };
     }
 
     @SuppressWarnings("unchecked")
     protected <KEY> KEY xconvertFK2PKImplicitly(String referrerPropertyClass<?> fkTypeClass<?> pkTypeObject fkValue) {
         // DB-able entity does not support optional for property
         // only supported in immutable entity
         final KEY realValue;
         if (fkType.equals(pkType)) { // basically true
             realValue = (KEY) fkValue;
         } else { // different type (needs implicit conversion)
             if (String.class.equals(pkType)) { // e.g. Integer to String
                 realValue = (KEY) fkValue.toString();
             } else if (Number.class.isAssignableFrom(pkType)) { // e.g. Long to Integer
                 realValue = (KEY) DfTypeUtil.toNumber(fkValuepkType);
             } else if (Date.class.isAssignableFrom(fkType)) {
                 if (Date.class.equals(pkType)) { // e.g. Timestamp to Date
                     realValue = (KEY) new Date(((DatefkValue).getTime());
                 } else if (Timestamp.class.equals(pkType)) { // e.g. Date to Timestamp
                     realValue = (KEY) new Timestamp(((DatefkValue).getTime());
                 } else { // cannot conversion
                     realValue = (KEY) fkValue;
                 }
             } else { // cannot conversion
                 realValue = (KEY) fkValue;
             }
         }
         return realValue;
     }
 
     protected Object xconvertToRelationOptionalEntityIfNeeds(Object localEntityRelationInfo reverseInfo) {
         final Object writtenObj;
         if (isRelationOptional(reverseInfo.getPropertyAccessType())) {
             writtenObj = toRelationOptional(reverseInfo.getRelationPropertyName(), localEntity);
         } else {
             writtenObj = localEntity;
         }
         return writtenObj;
     }
 
     // -----------------------------------------------------
     //                                   Ancient Entry Point
     //                                   -------------------
     
Help load referrer internally. (ancient entry point)
About internal policy, the value of primary key(and others too) is treated as CaseInsensitive.

Parameters:
<LOCAL_ENTITY> The type of base entity.
<KEY> The type of primary key.
<REFERRER_CB> The type of referrer condition-bean.
<REFERRER_ENTITY> The type of referrer entity.
localEntityList The list of local entity. (NotNull)
loadReferrerOption The option of loadReferrer. (NotNull)
callback The internal callback of loadReferrer. (NotNull)
Returns:
The callback to load nested referrer. (NotNull)
 
     protected <LOCAL_ENTITY extends Entity, KEY, REFERRER_CB extends ConditionBean, REFERRER_ENTITY extends Entity// generic
     NestedReferrerListGateway<REFERRER_ENTITY> helpLoadReferrerInternally(List<LOCAL_ENTITY> localEntityList,
             LoadReferrerOption<REFERRER_CB, REFERRER_ENTITY> loadReferrerOption,
             InternalLoadReferrerCallback<LOCAL_ENTITY, KEY, REFERRER_CB, REFERRER_ENTITY> callback) {
         return doHelpLoadReferrerInternally(localEntityListloadReferrerOptioncallback);
     }
 
     protected <LOCAL_ENTITY extends Entity, KEY, REFERRER_CB extends ConditionBean, REFERRER_ENTITY extends Entity// generic
     NestedReferrerListGateway<REFERRER_ENTITY> doHelpLoadReferrerInternally(List<LOCAL_ENTITY> localEntityList,
             LoadReferrerOption<REFERRER_CB, REFERRER_ENTITY> loadReferrerOption,
             final InternalLoadReferrerCallback<LOCAL_ENTITY, KEY, REFERRER_CB, REFERRER_ENTITY> callback) {
         // - - - - - - - - - -
         // Assert precondition
         // - - - - - - - - - -
         assertBehaviorSelectorNotNull("loadReferrer");
         assertObjectNotNull("localEntityList"localEntityList);
         assertObjectNotNull("loadReferrerOption"loadReferrerOption);
         if (localEntityList.isEmpty()) {
             @SuppressWarnings("unchecked")
             final NestedReferrerListGateway<REFERRER_ENTITY> empty = (NestedReferrerListGateway<REFERRER_ENTITY>) ;
             return empty;
         }
 
         // - - - - - - - - - - - - - -
         // Prepare temporary container
         // - - - - - - - - - - - - - -
         final Map<KEY, LOCAL_ENTITY> pkLocalEntityMap = new LinkedHashMap<KEY, LOCAL_ENTITY>();
         final Set<KEY> pkSet = new LinkedHashSet<KEY>(); // might be same PK e.g. when entity of pull-out
         for (LOCAL_ENTITY localEntity : localEntityList) {
             final KEY primaryKeyValue = callback.getPKVal(localEntity);
             if (primaryKeyValue == null) {
                 String msg = "PK value of local entity should not be null: " + localEntity;
                 throw new IllegalArgumentException(msg);
             }
             pkSet.add(primaryKeyValue);
             pkLocalEntityMap.put(toLoadReferrerMappingKey(primaryKeyValue), localEntity);
         }
 
         // - - - - - - - - - - - - - - - -
         // Prepare referrer condition bean
         // - - - - - - - - - - - - - - - -
         final REFERRER_CB cb;
         if (loadReferrerOption.getReferrerConditionBean() != null) {
             cb = loadReferrerOption.getReferrerConditionBean();
         } else {
             cb = callback.newMyCB();
         }
 
         // - - - - - - - - - - - - - -
         // Select the list of referrer
         // - - - - - - - - - - - - - -
         callback.qyFKIn(cbpkSet);
         final String referrerPropertyName = callback.getRfPrNm();
         final String fixedCondition = xbuildReferrerCorrelatedFixedCondition(cbreferrerPropertyName);
         final String basePointAliasName = cb.getSqlClause().getBasePointAliasName();
         final boolean hasFixedCondition = fixedCondition != null && fixedCondition.trim().length() > 0;
         if (hasFixedCondition) {
             cb.getSqlClause().registerWhereClause(fixedConditionbasePointAliasName);
         }
             public void query(ConditionBean unionCB) {
                 @SuppressWarnings("unchecked")
                 REFERRER_CB referrerUnionCB = (REFERRER_CB) unionCB;
                 // for when application uses union query in condition-bean set-upper.
                 callback.qyFKIn(referrerUnionCBpkSet);
                 if (hasFixedCondition) {
                     referrerUnionCB.getSqlClause().registerWhereClause(fixedConditionbasePointAliasName);
                 }
             }
         });
         if (pkSet.size() > 1) {
             callback.qyOdFKAsc(cb);
         }
         loadReferrerOption.delegateConditionBeanSettingUp(cb);
         if (cb.getSqlClause().hasSpecifiedSelectColumn(basePointAliasName)) {
             callback.spFKCol(cb); // specify required columns for relation
         }
         final List<REFERRER_ENTITY> referrerList = callback.selRfLs(cb);
         loadReferrerOption.delegateEntitySettingUp(referrerList);
 
         // - - - - - - - - - - - - - - - - - - - - - - - -
         // Create the map of {primary key / referrer list}
         // - - - - - - - - - - - - - - - - - - - - - - - -
         final Map<KEY, List<REFERRER_ENTITY>> pkReferrerListMap = new LinkedHashMap<KEY, List<REFERRER_ENTITY>>();
         for (REFERRER_ENTITY referrerEntity : referrerList) {
             final KEY referrerListKey;
             {
                 final KEY foreignKeyValue = callback.getFKVal(referrerEntity);
                 referrerListKey = toLoadReferrerMappingKey(foreignKeyValue);
             }
             if (!pkReferrerListMap.containsKey(referrerListKey)) {
                 pkReferrerListMap.put(referrerListKeynew ArrayList<REFERRER_ENTITY>());
             }
             (pkReferrerListMap.get(referrerListKey)).add(referrerEntity);
 
             // for Reverse Reference.
             final LOCAL_ENTITY localEntity = pkLocalEntityMap.get(referrerListKey);
             callback.setlcEt(referrerEntitylocalEntity);
         }
 
         // - - - - - - - - - - - - - - - - - -
         // Relate referrer list to base entity
         // - - - - - - - - - - - - - - - - - -
         for (LOCAL_ENTITY localEntity : localEntityList) {
             final KEY referrerListKey;
             {
                 final KEY primaryKey = callback.getPKVal(localEntity);
                 referrerListKey = toLoadReferrerMappingKey(primaryKey);
             }
             if (pkReferrerListMap.containsKey(referrerListKey)) {
                 callback.setRfLs(localEntitypkReferrerListMap.get(referrerListKey));
             } else {
                 callback.setRfLs(localEntitynew ArrayList<REFERRER_ENTITY>());
             }
         }
 
         // - - - - - - - - - - - - - - - - - - - -
         // Return callback to load nested referrer
         // - - - - - - - - - - - - - - - - - - - -
         return new NestedReferrerListGateway<REFERRER_ENTITY>() {
             public void withNestedReferrer(ReferrerListHandler<REFERRER_ENTITY> handler) {
                 handler.handle(Collections.unmodifiableList(referrerList));
             }
         };
     }
 
     protected String xbuildReferrerCorrelatedFixedCondition(ConditionBean cbString referrerPropertyName) {
         if (referrerPropertyName == null) {
             return null;
         }
         final DBMeta localDBMeta = asDBMeta();
         if (!localDBMeta.hasReferrer(referrerPropertyName)) { // one-to-one referrer
             return null;
        }
        final ReferrerInfo referrerInfo = localDBMeta.findReferrerInfo(referrerPropertyName);
        return xdoBuildReferrerCorrelatedFixedCondition(cbreferrerInfo);
    }
        final RelationInfo reverseRelation = referrerInfo.getReverseRelation();
        if (reverseRelation == null) {
            return null;
        }
        if (!(reverseRelation instanceof ForeignInfo)) {
            String msg = "The reverse relation (referrer's reverse) should be foreign info: " + referrerInfo;
            throw new IllegalStateException(msg);
        }
        final ForeignInfo foreignInfo = (ForeignInforeverseRelation;
        final String fixedCondition = foreignInfo.getFixedCondition();
        if (fixedCondition == null || fixedCondition.trim().length() == 0) {
            return null;
        }
        final String localAliasMark = .;
        final String basePointAliasName = cb.getSqlClause().getBasePointAliasName();
        return Srl.replace(fixedConditionlocalAliasMarkbasePointAliasName);