Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Business Objects
Panel
nameblue
id0

Business objects (BOs) implement the software's business logic. They Basically they are entity managers responsible for handling data objects (constructing, loading, saving, deleting) and any other business logic related with to the business modulespecific entity. For every data object, there is a business object that handles it. Business objects do not implement any process flows, but offer offer services to the Controller layer (UI, API, Process)) but they do not implement any process flows.

In CRM.COM Software, we implement the business object classes are implemented using EJBs (Enterprise Java Beans) J2EE server-side components, and more specifically we use , Stateless Session Beans. More information about EJBs can be found here.


What does this section cover?

Table of Contents


Creating the Business Object Classes

The first thing to do is to create an EJB that will handle our business objects. In order to create our class we must first decide the name of the package to place it in. Based on the business structure, the respective packages should be created. Based on CRM.COM naming conventions, all business objects are stored in the All business objects should be placed under com.crm.businessobject package. Based on the module we are implementing, further packages are then created in here.

 

In this case, we will create the package .* named packages, and extend either com.crm.businessobject.accounts that will contain the module's business object classes, and create the CRMBOBankBean.java business object class.CRMBO or one of its subclasses and follow this naming convention: CRMBO<entityname>Bean.java. 

...

Expand
titleCreating CRMBOBankBeanCRMBOBankBranchBean.java

Image Removed

Image Removed

 

Note that on EJB creation, we also specify the super class of the class we are creating, depending on the business logic of our class. In this case we select the com.crm.businessobject.CRMBO as the super class.


Image Added Image Added

Creating EJB References

To create an EJB reference, you must use @EJB annotation followed by the modifier, the name of the EJB class and the reference name.

Code Block
titleEJB References
collapsetrue
public class CRMBOBankBranchBean extends CRMBOMasterEntity {
	private static final long serialVersionUID = 1L;
	
	@EJB private CRMBOAccountReceivableBean accountReceivableBean;
	@EJB private CRMValidatorBean validatorBean;
	...
}

Defining Basic BO Methods

To implement the basic business logic in our class, we will need to create the following methods must be created:


The following method creates a new instance of the data object adding any business logic required.

Code Block
language
languagejava
themeEclipse
javatitleconstructDO
collapsetrue
     /**
     * Constructs a bank branch.
     * 
     * @param mainDTO - the main data object
     * @return a bank branch
     * @throws Exception
     */
	@Override
	protected CRMDO constructDO(CRMDO mainDTO) throws Exception {
		
		CRMDOBankBranch bankBranch = new CRMDOBankBranch();
		
		if (mainDTO instanceof CRMDOBank)
		{
		...	bankBranch.setBank((CRMDOBank)mainDTO);
		}
		
		return bankBranch;
	}

This method creates a new instance of the data object. In this method we add any business logic required when creating a new entity. The mainDTO parameter is not null in case the data object to be created should be related with another data object.

 

...


...

The following method saves the data objects to the database. Any business logic required can be added (i.e. saving related data objects).

isModified method, which is implemented in com.crm.dataobject.CRMDO class, is used to check if the data object has been modified.

saveDataObject(CRMDO dto) method, which is implemented in com.crm.businessobject.CRMBO class, must be used for saving a data object.

Code Block
languagejava
themeEclipse
titlesaveDO
collapsetrue
    /**
     * Saves a bank branch.
     * 
     * @param dto - the bank branch to save
     * @return the saved bank branch
     * @throws Exception
     */
	@Override
	protected CRMDO saveDO(CRMDO dto) throws Exception {
		
		...CRMDOBankBranch bankBranch = (CRMDOBankBranch)dto;
		
		if (bankBranch.isModified()) 
		{
			saveDataObject(bankBranch);
		}
		
		return bankBranch;
	}


This method saves deletes the data objects to the database. In this method we this method, we add any business logic required to required to be executed when saving deleting an entity .(i.e. deleting related data objects). Note that records are not physically deleted but marked as deleted. 

Code Block
languagejava
themeEclipselanguagejava
titledeleteDO
collapsetrue
    /**
     * Deletes a bank branch.
     * 
     * @param dto - the bank branch to delete
     * @return the deleted bank branch
     * @throws Exception
     */
	@Override
	protected CRMDO deleteDO(CRMDO dto) throws Exception {
		...return dto;
	}


This method deletes validates the data objects . In this method we add any business logic required to be executed when deleting an entity. Note that records are not physically deleted but marked as deleted. 

 

...

before saving to the database. Any validations that should be done before saving the data object to the database should be performed in this method.

Code Block
languagejava
themeEclipse
titlevalidateDOonSave
collapsetrue
     /**
     * Validates a bank branch on save.
     * 
     * @param dto - the bank branch to validate
     * @throws Exception
     */
	@Override
	protected void validateDOonSave(CRMDO dto) throws Exception {
		CRMDOBankBranch bankBranch = (CRMDOBankBranch)dto;
		validateUniqueness(bankBranch);
	}


This method can be used in cases where the data object must be unique.  validateUniqueRecordAgainstDb and validateUniqueValueComboAgainstDb of CRMValidatorBean.java can be used to validate that there is no other data object having the same field value or having the same combination of fields values respectively.

Code Block
languagejava
themeEclipse
titlevalidateUniqueness
collapsetrue
     /**
     * Validates the uniqueness of a bank branch.
     * 
     * @param bankBranch - the bank branch to validate
     * @throws Exception
     */
	protected void validateUniqueness(CRMDOBankBranch bankBranch) throws Exception {
		//Validate that there is no other bank branch with the same name
		validatorBean.validateUniqueRecordAgainstDb(
				bankBranch, 
				new String[]{"name"}, 
				new String[]{"Name"}, 
				"Branch", 
				true, 
				null);
		
		//Validate that there is no other bank branch with the same alternative code
		validatorBean.validateUniqueRecordAgainstDb(
				bankBranch, 
				new String[]{"altCode"}, 
				new String[]{"Alternative Code"}, 
				"Branch", 
				true, 
				null);


This method validates the data objects before saving to the database as deleted. Any validations that should be done before saving deleting the data object to the database should be performed in this method. 

code
Code Block
language
java
themeEclipse
languagejava
titlevalidateDOonDelete
collapsetrue
    /**
     * Validates a bank branch on delete.
     * 
     * @param dto - the bank branch to validate
     * @throws Exception
     */
	@Override
	protected void validateDOonDelete(CRMDO dto) throws Exception {
		...
		CRMDOBankBranch bankBranch = (CRMDOBankBranch)dto;
    	
		//Validate that the bank branch is not defined in any non-terminated accounts receivable payment preference
		validateIfUsedByAccountsOnDelete(bankBranch);
	}


This method validates returns the class of the data objects before saving to the database as deleted. Any validations that should be done before deleting the data object should be performed in this method.

 

...

object that is handled by the specific business object. It is used mainly to construct the HQL (Hibernate Query Language) dynamically.

Code Block
languagejava
themeEclipselanguagejava
titlegetDataObjectClass
collapsetrue
    /**
     * Returns the data object class of a bank branch.
     * 
     * @return the data object class of the bank branch
     */
	@Override
	protected Class<CRMDOBank>Class<CRMDOBankBranch> getDataObjectClass() {
		return CRMDOBankCRMDOBankBranch.class;
	}


This method returns the class a list of the associated data object that is handled by the specific business objects that should be loaded by default when loading a data object. It is used mainly to construct the HQL (Hibernate Query Language) dynamically.

 

...

called by abstract functionality to load the data objects associated data objects.

Code Block
languagejava
themeEclipse
languagejava
titlegetDefaultAssociations
collapsetrue
     /**
     * Returns the default associated data objects of a bank branch.
     * 
     * @return the default associated data objects of the bank branch
     */
	@Override
	public ArrayList<String> getDefaultAssociations() {
		
		ArrayList<String> defaultAssociations = new ArrayList<String>();
		
		defaultAssociations.add("createdByUser");
		defaultAssociations.add("updatedByUser");
		defaultAssociations.add("createdByUnit");
		defaultAssociations.add("updatedByUnit");
		defaultAssociations.add("bank");
		
		return defaultAssociations;
	}


This method returns a list of the associated data objects that should be loaded by default when loading a data objectsequence number that is set on the data object in case it has a number property. It is called by abstract functionality to load set the data objects associated data objects.

 

...

object's number when saving the data object.

Code Block
languagejava
themeEclipselanguagejava
titleExample 1:getSequenceNumber
collapsetrue
    /**
     * Returns the next sequence number of a bank branch.
     * 
     * @param dto - the bank branch to return the next sequence number for
     * @return the next sequence number of the bank branch
     * @throws Exception
     */
	@Override
	protected String getSequenceNumber(CRMDO dto) throws Exception {
		//No sequence number must be returned
		return null;
	}


Use getNextNumber(String tableName) method which is implemented in com.crm.businessobject.platform.CRMBONumberSchemeBean, to get the next sequence number of the data object.

Code Block
languagejava
themeEclipse
titleExample 2: getSequenceNumber
collapsetrue
    /**
     * Returns the next sequence number of an account definition.
     * 
     * @param dto - the account definition to return the next sequence number for
     * @return the next sequence number of the account definition
     * @throws Exception
     */
	@Override
	protected String getSequenceNumber(CRMDO dto) throws Exception {
		return numberSchemeBean.getNextNumber("JOBS");
	}


This method returns a sequence number that is set on the data object in case it has a number property. It list of the data object's mandatory fields (fields that should be always set). This method is called by abstract functionality to set the data object's number when saving the data object.

 

...

validate that all mandatory fields are set.

Code Block
languagejava
themeEclipselanguagejava
titlegetMandatoryFields
collapsetrue
    /**
     * Returns the mandatory fields of a bank branch.
     * 
     * @param dto - the bank branch to return the mandatory fields for
     * @return the mandatory fields of the bank branch
     * @throws Exception
     */
	@Override
	protected LinkedHashMap<String, String> getMandatoryFields(CRMDO dto) throws Exception {
		
		LinkedHashMap<String, String> mandatoryFields = new LinkedHashMap<String, String>();
		
		mandatoryFields...put("key_name", "name");
		mandatoryFields.put("key_alternative_code", "altCode");
		
		return mandatoryFields;
	}

Defining Additional BO methods

In most cases, the basic business object methods are not enough and some additional methods need to be created.


In the following examples load(String criteria, ArrayList values, ArrayList<String> associations, String orderBy, Integer maxSize) method of com.crm.businessobject.platform.CRMBO is used to load the list data objects based on the given criteria.

HQL must be used to construct the criteria string parameter.


This method returns a list of bank branches of a given bank.

Code Block
languagejava
titleload(CRMDOBank bank)
collapsetrue
	/**
     * Loads a list of bank branches of

...

 a bank.
     * 
     * @param bank - the bank to load the branches for
     * @return a list of bank branches of the bank
     * @throws Exception
     */
	public ArrayList<CRMDO> load(CRMDOBank bank) throws Exception {
		
		ArrayList<String> values = new ArrayList<String>();
		values.add(bank.getId());
		return load(
				getDOName().toLowerCase() + ".bank.id=:p1 and " + 
				getDOName().toLowerCase() + ".isDeleted=0",
				values,
				getDefaultAssociations(),
				null,
				null);
	}


This method loads the bank branch having the given alternative code.

Code Block
languagejava
titleload(CRMDOBank bank)
collapsetrue
	/**
	 * Loads a bank branch by an alternative code.
	 * 
	 * @param altCode - the alternative code to load by
	 * @param associations - a list of associated objects
	 * @return a bank branch with the given alternative code
	 * @throws Exception
	 */
	public CRMDOBankBranch loadByAltCode(String altCode, ArrayList<String> associations) throws Exception {
		
		ArrayList<String> values = new ArrayList<String>();
		values.add(altCode);
		
		return (CRMDOBankBranch)load(
				getDOName().toLowerCase() + ".altCode=:p1 and " +
				getDOName().toLowerCase() + ".isDeleted=0", 
				values, 
				associations);
	}


The following method loads a list of non-terminated accounts that have a given bank branch defined in their payment preferences set. This method is implemented in com.crm.businessobject.accounts.CRMBOAccountReceivableBean class.

Code Block
languagejava
titleloadNonTerminated(CRMDOBankBranch bankBranch)
collapsetrue
/**
     * Loads a list of non terminated accounts by a given bank branch
     * 
     * @param bankBranch - the bank branch to load the accounts for
     * @return a list of non terminated accounts
     * @throws Exception
     */
	public ArrayList<CRMDO> loadNonTerminated(CRMDOBankBranch bankBranch) throws Exception {
		
		ArrayList<String> values = new ArrayList<String>();
		
		String criteria = "";		
		
		
		if (bankBranch!=null)
		{
			values.add(bankBranch.getId());
			
			criteria += 
					" and exists ( " + 
					"   select accountpaymentpreference.id from " + CRMDOAccountPaymentPreference.class.getSimpleName() + " accountpaymentpreference " +
					"   left join accountpaymentpreference.account " +
					"   left join accountpaymentpreference.bankBranch " +
					"   where accountpaymentpreference.bankBranch.id=:p" + values.size() + " and " +
					"   accountpaymentpreference.account.id=" + getDOName().toLowerCase() + ".id and " +
					"   accountpaymentpreference.isDeleted=0 " + 
					" )";
		}
				
		return load(
				getDOName().toLowerCase() + ".lifeCycleState!='" + AccountReceivableLifeCycleState.TERMINATED + "' and " + 
				getDOName().toLowerCase() + ".isDeleted=0" + criteria, 
				values, 
				associations, 
				null, 
				null);
	}


To start implementing the controller layer, go to Developing the Controller layer