[go: nahoru, domu]

Jump to content

Composite entity pattern: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
No edit summary
Monkbot (talk | contribs)
m Task 18 (cosmetic): eval 2 templates: del empty params (4×); hyphenate params (1×);
 
(13 intermediate revisions by 11 users not shown)
Line 1: Line 1:
'''Composite entity''' is a [[Java Platform, Enterprise Edition|Java EE]] [[Software design pattern]] and it is used to model, represent, and manage a set of interrelated persistent objects rather that representing them as individual fine-grained entity beans, and also a composite entity bean represents a graph of objects.<ref name=":o_cjp">{{Cite web|url = http://www.oracle.com/technetwork/java/compositeentity-141992.html|title = Core J2EE Patterns - Composite Entity|date = |accessdate = 6 February 2016|website = Oracle|publisher = Oracle|last = |first = }}</ref>
'''Composite entity''' is a [[Java Platform, Enterprise Edition|Java EE]] [[Software design pattern]] and it is used to model, represent, and manage a set of interrelated persistent objects rather than representing them as individual fine-grained entity beans, and also a composite entity bean represents a graph of objects.<ref name=":o_cjp">{{Cite web|url = http://www.oracle.com/technetwork/java/compositeentity-141992.html|title = Core J2EE Patterns - Composite Entity|access-date = 6 February 2016|website = Oracle|publisher = Oracle}}</ref>


==Structure==
==Structure==
there are a number of strategies to implement composite entity pattern. This pattern mainly composites of compsite entity, coarse-grained object,dependent objects.<ref name=":o_cjp"/>
There are a number of strategies to implement composite entity pattern. This pattern mainly composites of composite entity, coarse-grained object, and dependent objects.<ref name=":o_cjp"/>

[[File:Composte entity pattern class diagram.png|center|Composite entity pattern class diagram]]

<!-- Deleted image removed: [[File:Composite entity pattern sequence diagram.png|center|Composite entity pattern sequence diagram]] -->

===Composite entity component===
===Composite entity component===
Composite entity is the coarse-grained entity bean which may be the coarse-grained object, or may contain a reference to the coarse-grained object.<ref name=":o_cjp"/>
Composite entity is the coarse-grained entity bean which may be the coarse-grained object, or may contain a reference to the coarse-grained object.<ref name=":o_cjp"/>

===Coarse-grained object===
===Coarse-grained object===
A coarse-grained object is an object with its own life cycyle manages its own relationships to other objects. It can an object contained in the composite entity, or, composite entity itself can be the coarse-grained object which holds dependent objects.<ref name=":o_cjp"/>
A coarse-grained object is an object with its own life cycle manages its own relationships to other objects. It can be an object contained in the composite entity, or, composite entity itself can be the coarse-grained object which holds dependent objects.<ref name=":o_cjp"/>

===Dependent objects===
===Dependent objects===
It is an object, which can contain other dependent objects (there may be a tree of objects within the composite entity), that depends on the coarse-grained object and has its life cycle managed by the coarse-grained object.<ref name=":o_cjp"/>
It is an object, which can contain other dependent objects (there may be a tree of objects within the composite entity), that depends on the coarse-grained object and has its life cycle managed by the coarse-grained object.<ref name=":o_cjp"/>

==Consequences==
==Consequences==
According to Oracle description of the pattern, consequences includes eliminating inter-entity relationships, improving manageability by reducing entity beans, improving network performance, reducing database schema dependency, incresing object granularity, facicilitating composite transfer object creation and overhead of multi-level dependent object graphes.<ref name=":o_cjp"/>
According to Oracle description of the pattern, consequences include eliminating inter-entity relationships, improving manageability by reducing entity beans, improving network performance, reducing database schema dependency, increasing object granularity, facilitating composite transfer object creation and overhead of multi-level dependent object graphs.<ref name=":o_cjp"/>

===Drawbacks===
===Drawbacks===
The fatal drawback is the requirement of bean-managed persistent (BMP) [[JavaBeans|bean]]. This involves more work for developers, and craete some problems as follows:
The fatal drawback is the requirement of bean-managed persistent (BMP) [[JavaBeans|bean]]. This involves more work for developers, and create some problems as follows:
* materializing all the data in a coarse-grained entity whenever it's accessed, is unacceptably expensive
* materializing all the data in a coarse-grained entity whenever it is accessed, is unacceptably expensive
* In [[Java (programming language)|Java]], implementation of the ejbStore() method needs to be smart enough to avoid issuing all the updates required to persist the entire state of the object, unless the data has changed in all the persistent objects.
* In [[Java (programming language)|Java]], implementation of the ejbStore() method needs to be smart enough to avoid issuing all the updates required to persist the entire state of the object, unless the data has changed in all the persistent objects.
Composite entity pattern can only be implemented using BMP or by adding more hand-coded persistence logic to comtainer managed persistance (CMP) [[JavaBeans|beans]]. These both approaches reduce the maintainability.<ref name=":eojdad">{{Cite book|title = Expert One-on-One J2EE Design and Development|last = Johnson|first = R. |publisher = Wiley Publishing, Inc|year = 2003|location = Indianapolis|volume = |pages = 290}}</ref>
Composite entity pattern can only be implemented using BMP or by adding more hand-coded persistence logic to container managed persistence (CMP) [[JavaBeans|beans]]. These both approaches reduce the maintainability.<ref name=":eojdad">{{Cite book|title = Expert One-on-One J2EE Design and Development|last = Johnson|first = R. |publisher = Wiley Publishing, Inc|year = 2003|location = Indianapolis|pages = 290}}</ref>


==Sample code==
==Sample code==
Sample code for a Professional Service Automation application (PSA) in which the resource object is implmented via composite entity pattern, may look like as follows (entity implements coarse-grained object):
Sample code for a Professional Service Automation application (PSA) in which the resource object is implemented via composite entity pattern, may look like as follows (entity implements coarse-grained object):
<source lang="Java">
<syntaxhighlight lang="java">
package corepatterns.apps.psa.ejb;
package corepatterns.apps.psa.ejb;


Line 31: Line 40:


public class ResourceEntity implements EntityBean {
public class ResourceEntity implements EntityBean {
public String employeeId;
public String employeeId;
public String lastName;
public String lastName;
public String firstName;
public String firstName;
public String departmentId;
public String departmentId;
public String practiceGroup;
public String practiceGroup;
public String title;
public String title;
public String grade;
public String grade;
public String email;
public String email;
public String phone;
public String phone;
public String cell;
public String cell;
public String pager;
public String pager;
public String managerId;
public String managerId;
// Collection of BlockOutTime Dependent objects
// Collection of BlockOutTime Dependent objects
public Collection blockoutTimes;
public Collection blockoutTimes;


// Collection of SkillSet Dependent objects
// Collection of SkillSet Dependent objects
public Collection skillSets;
public Collection skillSets;


...
...


private EntityContext context;
private EntityContext context;
// Entity Bean methods implementation
// Entity Bean methods implementation
public String ejbCreate(ResourceTO resource) throws
public String ejbCreate(ResourceTO resource) throws
CreateException {
CreateException {
try {
try {
this.employeeId = resource.employeeId;
this.employeeId = resource.employeeId;
setResourceData(resource);
setResourceData(resource);
getResourceDAO().create(resource);
getResourceDAO().create(resource);
} catch(Exception ex) {
} catch(Exception ex) {
throw new EJBException("Reason:" + ...);
throw new EJBException("Reason:" + ...);
}
}
return this.employeeId;
return this.employeeId;
}
}
public String ejbFindByPrimaryKey(String primaryKey)
public String ejbFindByPrimaryKey(String primaryKey)
throws FinderException {
throws FinderException {
boolean result;
boolean result;
try {
try {
ResourceDAO resourceDAO = getResourceDAO();
ResourceDAO resourceDAO = getResourceDAO();
result =
result =
resourceDAO.selectByPrimaryKey(primaryKey);
resourceDAO.selectByPrimaryKey(primaryKey);
} catch(Exception ex) {
} catch(Exception ex) {
throw new EJBException("Reason:" + ...);
throw new EJBException("Reason:" + ...);
}
if (result) {
return primaryKey;
}
else {
throw new ObjectNotFoundException(...);
}
}
}
if(result) {
public void ejbRemove() {
return primaryKey;
try {
// Remove dependent objects
if (this.skillSets != null) {

SkillSetDAO skillSetDAO = getSkillSetDAO();
skillSetDAO.setResourceID(employeeId);
skillSetDAO.deleteAll();
skillSets = null;
}
if (this.blockoutTime != null) {
BlockOutTimeDAO blockouttimeDAO =
getBlockOutTimeDAO();
blockouttimeDAO.setResourceID(employeeId);
blockouttimeDAO.deleteAll();
blockOutTimes = null;
}

// Remove the resource from the persistent store
ResourceDAO resourceDAO = new
ResourceDAO(employeeId);
resourceDAO.delete();
} catch(ResourceException ex) {
throw new EJBException("Reason:"+...);
} catch(BlockOutTimeException ex) {
throw new EJBException("Reason:"+...);
} catch(Exception exception) {
...
}
}
}
public void setEntityContext(EntityContext context)
else {
{
throw new ObjectNotFoundException(...);
this.context = context;
}
}
}
public void unsetEntityContext() {
context = null;
public void ejbRemove() {
try {
}
// Remove dependent objects
public void ejbActivate() {
if(this.skillSets != null) {
employeeId = (String)context.getPrimaryKey();
}
public void ejbPassivate() {
employeeId = null;
}
public void ejbLoad() {
try {
// load the resource info from
ResourceDAO resourceDAO = getResourceDAO();
setResourceData((ResourceTO)
resourceDAO.load(employeeId));
// Load other dependent objects, if necessary
...
} catch(Exception ex) {
throw new EJBException("Reason:" + ...);
}
}
public void ejbStore() {
try {
// Store resource information
getResourceDAO().update(getResourceData());


// Store dependent objects as needed
SkillSetDAO skillSetDAO = getSkillSetDAO();
...
skillSetDAO.setResourceID(employeeId);
} catch(SkillSetException ex) {
skillSetDAO.deleteAll();
throw new EJBException("Reason:" + ...);
skillSets = null;
} catch(BlockOutTimeException ex) {
}
throw new EJBException("Reason:" + ...);
if(this.blockoutTime != null) {
}
BlockOutTimeDAO blockouttimeDAO =
getBlockOutTimeDAO();
...
blockouttimeDAO.setResourceID(employeeId);
blockouttimeDAO.deleteAll();
blockOutTimes = null;
}

// Remove the resource from the persistent store
ResourceDAO resourceDAO = new
ResourceDAO(employeeId);
resourceDAO.delete();
} catch(ResourceException ex) {
throw new EJBException("Reason:"+...);
} catch(BlockOutTimeException ex) {
throw new EJBException("Reason:"+...);
} catch(Exception exception) {
...
}
}
public void ejbPostCreate(ResourceTO resource) {
}
public void setEntityContext(EntityContext context)
{
this.context = context;
}
public void unsetEntityContext() {
context = null;
}
public void ejbActivate() {
employeeId = (String)context.getPrimaryKey();
}
public void ejbPassivate() {
employeeId = null;
}
public void ejbLoad() {
try {
// load the resource info from
ResourceDAO resourceDAO = getResourceDAO();
setResourceData((ResourceTO)
resourceDAO.load(employeeId));
// Load other dependent objects, if necessary
...
} catch(Exception ex) {
throw new EJBException("Reason:" + ...);
}
}
}
public void ejbStore() {
try {
// Store resource information
getResourceDAO().update(getResourceData());


// Store dependent objects as needed
// Method to Get Resource Transfer Object
public ResourceTO getResourceTO() {
...
// create a new Resource Transfer Object
} catch(SkillSetException ex) {
ResourceTO resourceTO = new
throw new EJBException("Reason:" + ...);
ResourceTO(employeeId);
} catch(BlockOutTimeException ex) {

throw new EJBException("Reason:" + ...);
// copy all values
resourceTO.lastName = lastName;
resourceTO.firstName = firstName;
resourceTO.departmentId = departmentId;
...
return resourceTO;
}
}
...
}
public void ejbPostCreate(ResourceTO resource) {
}


public void setResourceData(ResourceTO resourceTO) {
// Method to Get Resource Transfer Object
// copy values from Transfer Object into entity bean
public ResourceTO getResourceTO() {
employeeId = resourceTO.employeeId;
// create a new Resource Transfer Object
lastName = resourceTO.lastName;
ResourceTO resourceTO = new
ResourceTO(employeeId);
...
}


// Method to get dependent Transfer Objects
// copy all values
public Collection getSkillSetsData() {
resourceTO.lastName = lastName;
// If skillSets is not loaded, load it first.
resourceTO.firstName = firstName;
// See Lazy Load strategy implementation.
resourceTO.departmentId = departmentId;

return skillSets;
}
...
...
return resourceTO;
}


// other get and set methods as needed
public void setResourceData(ResourceTO resourceTO) {
// copy values from Transfer Object into entity bean
employeeId = resourceTO.employeeId;
lastName = resourceTO.lastName;
...
...
}


// Entity bean business methods
// Method to get dependent Transfer Objects
public Collection getSkillSetsData() {
public void addBlockOutTimes(Collection moreBOTs)
throws BlockOutTimeException {
// If skillSets is not loaded, load it first.
// Note: moreBOTs is a collection of
// See Lazy Load strategy implementation.
// BlockOutTimeTO objects
try {
Iterator moreIter = moreBOTs.iterator();
while (moreIter.hasNext()) {
BlockOutTimeTO botTO = (BlockOutTimeTO)
moreIter.next();
if (! (blockOutTimeExists(botTO))) {
// add BlockOutTimeTO to collection
botTO.setNew();
blockOutTime.add(botTO);
} else {
// BlockOutTimeTO already exists, cannot add
throw new BlockOutTimeException(...);
}
}
} catch(Exception exception) {
throw new EJBException(...);
}
}


public void addSkillSet(Collection moreSkills)
return skillSets;
throws SkillSetException {
}
// similar to addBlockOutTime() implementation
...
...

// other get and set methods as needed
...

// Entity bean business methods
public void addBlockOutTimes(Collection moreBOTs)
throws BlockOutTimeException {
// Note: moreBOTs is a collection of
// BlockOutTimeTO objects
try {
Iterator moreIter = moreBOTs.iterator();
while(moreIter.hasNext()) {
BlockOutTimeTO botTO = (BlockOutTimeTO)
moreIter.next();
if (! (blockOutTimeExists(botTO))) {
// add BlockOutTimeTO to collection
botTO.setNew();
blockOutTime.add(botTO);
} else {
// BlockOutTimeTO already exists, cannot add
throw new BlockOutTimeException(...);
}
}
} catch(Exception exception) {
throw new EJBException(...);
}
}
}


public void addSkillSet(Collection moreSkills)
throws SkillSetException {
// similar to addBlockOutTime() implementation
...
...
}


public void updateBlockOutTime(Collection updBOTs)
...
throws BlockOutTimeException {

try {
public void updateBlockOutTime(Collection updBOTs)
Iterator botIter = blockOutTimes.iterator();
throws BlockOutTimeException {
Iterator updIter = updBOTs.iterator();
try {
Iterator botIter = blockOutTimes.iterator();
while (updIter.hasNext()) {
BlockOutTimeTO botTO = (BlockOutTimeTO)
Iterator updIter = updBOTs.iterator();
while (updIter.hasNext()) {
updIter.next();
BlockOutTimeTO botTO = (BlockOutTimeTO)
while (botIter.hasNext()) {
updIter.next();
BlockOutTimeTO existingBOT =
while (botIter.hasNext()) {
(BlockOutTimeTO) botIter.next();
// compare key values to locate BlockOutTime
BlockOutTimeTO existingBOT =
(BlockOutTimeTO) botIter.next();
if (existingBOT.equals(botTO)) {
// compare key values to locate BlockOutTime
// Found BlockOutTime in collection
// replace old BlockOutTimeTO with new one
if (existingBOT.equals(botTO)) {
botTO.setDirty(); //modified old dependent
// Found BlockOutTime in collection
// replace old BlockOutTimeTO with new one
botTO.resetNew(); //not a new dependent
botTO.setDirty(); //modified old dependent
existingBOT = botTO;
botTO.resetNew(); //not a new dependent
}
existingBOT = botTO;
}
}
}
} catch (Exception exc) {
throw new EJBException(...);
}
}
}
} catch (Exception exc) {
throw new EJBException(...);
}
}
}


public void updateSkillSet(Collection updSkills)
public void updateSkillSet(Collection updSkills)
throws CommitmentException {
throws CommitmentException {
// similar to updateBlockOutTime...
// similar to updateBlockOutTime...
...
...
}
}


...
...


}
}
</syntaxhighlight><ref name=":o_cjp"/>



</source><ref name=":o_cjp"/>
==See also==
==See also==
* [[Data transfer object]]
* [[Data transfer object]]
Line 272: Line 280:


{{Design Patterns patterns}}
{{Design Patterns patterns}}

[[Category:Software design patterns]]
[[Category:Software design patterns]]
[[Category:Articles with example Java code]]

Latest revision as of 20:14, 16 December 2020

Composite entity is a Java EE Software design pattern and it is used to model, represent, and manage a set of interrelated persistent objects rather than representing them as individual fine-grained entity beans, and also a composite entity bean represents a graph of objects.[1]

Structure[edit]

There are a number of strategies to implement composite entity pattern. This pattern mainly composites of composite entity, coarse-grained object, and dependent objects.[1]

Composite entity pattern class diagram
Composite entity pattern class diagram


Composite entity component[edit]

Composite entity is the coarse-grained entity bean which may be the coarse-grained object, or may contain a reference to the coarse-grained object.[1]

Coarse-grained object[edit]

A coarse-grained object is an object with its own life cycle manages its own relationships to other objects. It can be an object contained in the composite entity, or, composite entity itself can be the coarse-grained object which holds dependent objects.[1]

Dependent objects[edit]

It is an object, which can contain other dependent objects (there may be a tree of objects within the composite entity), that depends on the coarse-grained object and has its life cycle managed by the coarse-grained object.[1]

Consequences[edit]

According to Oracle description of the pattern, consequences include eliminating inter-entity relationships, improving manageability by reducing entity beans, improving network performance, reducing database schema dependency, increasing object granularity, facilitating composite transfer object creation and overhead of multi-level dependent object graphs.[1]

Drawbacks[edit]

The fatal drawback is the requirement of bean-managed persistent (BMP) bean. This involves more work for developers, and create some problems as follows:

  • materializing all the data in a coarse-grained entity whenever it is accessed, is unacceptably expensive
  • In Java, implementation of the ejbStore() method needs to be smart enough to avoid issuing all the updates required to persist the entire state of the object, unless the data has changed in all the persistent objects.

Composite entity pattern can only be implemented using BMP or by adding more hand-coded persistence logic to container managed persistence (CMP) beans. These both approaches reduce the maintainability.[2]

Sample code[edit]

Sample code for a Professional Service Automation application (PSA) in which the resource object is implemented via composite entity pattern, may look like as follows (entity implements coarse-grained object):

package corepatterns.apps.psa.ejb;

import corepatterns.apps.psa.core.*;
import corepatterns.apps.psa.dao.*;
import java.sql.*;
import javax.sql.*;
import java.util.*;
import javax.ejb.*;
import javax.naming.*;

public class ResourceEntity implements EntityBean {
    public String employeeId;
    public String lastName;
    public String firstName;
    public String departmentId;
    public String practiceGroup;
    public String title;
    public String grade;
    public String email;
    public String phone;
    public String cell;
    public String pager;
    public String managerId;
    
    // Collection of BlockOutTime Dependent objects
    public Collection blockoutTimes;

    // Collection of SkillSet Dependent objects
    public Collection skillSets;

    ...

    private EntityContext context;
// Entity Bean methods implementation
public String ejbCreate(ResourceTO resource) throws 
    CreateException {
        try {
            this.employeeId = resource.employeeId;
            setResourceData(resource);
            getResourceDAO().create(resource);
        } catch(Exception ex) {
            throw new EJBException("Reason:" + ...);
        }
        return this.employeeId;
}
    
public String ejbFindByPrimaryKey(String primaryKey) 
    throws FinderException {
        boolean result;
        try {
            ResourceDAO resourceDAO = getResourceDAO();
            result = 
                resourceDAO.selectByPrimaryKey(primaryKey);
        } catch(Exception ex) {
            throw new EJBException("Reason:" + ...);
        }
        if (result) {
            return primaryKey;
        }
        else {
            throw new ObjectNotFoundException(...);
        }
    }
    
    public void ejbRemove() {
        try {
            // Remove dependent objects
            if (this.skillSets != null) {

                SkillSetDAO skillSetDAO = getSkillSetDAO();
                skillSetDAO.setResourceID(employeeId);
                skillSetDAO.deleteAll();
                skillSets = null;
            }
            if (this.blockoutTime != null) {
                BlockOutTimeDAO blockouttimeDAO = 
                        getBlockOutTimeDAO();
                blockouttimeDAO.setResourceID(employeeId);
                blockouttimeDAO.deleteAll();
                blockOutTimes = null;
            }

            // Remove the resource from the persistent store
            ResourceDAO resourceDAO = new 
                ResourceDAO(employeeId);
            resourceDAO.delete();
        } catch(ResourceException ex) {
            throw new EJBException("Reason:"+...);
        } catch(BlockOutTimeException ex) {
            throw new EJBException("Reason:"+...);
        } catch(Exception exception) {
            ...
        }
    }
    public void setEntityContext(EntityContext context) 
    {
        this.context = context;
    }
    
    public void unsetEntityContext() {
        context = null;
    }
    
    public void ejbActivate() {
        employeeId = (String)context.getPrimaryKey();
    }
    
    public void ejbPassivate() {
        employeeId = null;
    }
    
    public void ejbLoad() {
        try {
            // load the resource info from
            ResourceDAO resourceDAO = getResourceDAO();
            setResourceData((ResourceTO) 
                resourceDAO.load(employeeId));
            
            // Load other dependent objects, if necessary
            ...
        } catch(Exception ex) {
            throw new EJBException("Reason:" + ...);
        }
    }
    
    public void ejbStore() {
        try {
            // Store resource information
            getResourceDAO().update(getResourceData());

            // Store dependent objects as needed
            ...
        } catch(SkillSetException ex) {
            throw new EJBException("Reason:" + ...);
        } catch(BlockOutTimeException ex) {
            throw new EJBException("Reason:" + ...);
        }
        ...
    }
    public void ejbPostCreate(ResourceTO resource) {
    }

    // Method to Get Resource Transfer Object
    public ResourceTO getResourceTO() {
        // create a new Resource Transfer Object
        ResourceTO resourceTO = new 
                ResourceTO(employeeId);

        // copy all values 
        resourceTO.lastName = lastName;
        resourceTO.firstName = firstName;
        resourceTO.departmentId = departmentId;
        ...
        return resourceTO;
    }

    public void setResourceData(ResourceTO resourceTO) {
        // copy values from Transfer Object into entity bean
        employeeId = resourceTO.employeeId;
        lastName = resourceTO.lastName;
        ...
    }

    // Method to get dependent Transfer Objects
    public Collection getSkillSetsData() {
        // If skillSets is not loaded, load it first.
        // See Lazy Load strategy implementation.

        return skillSets;    
    }
    ...

    // other get and set methods as needed
    ...

    // Entity bean business methods
    public void addBlockOutTimes(Collection moreBOTs) 
    throws BlockOutTimeException {
        // Note: moreBOTs is a collection of 
        // BlockOutTimeTO objects
        try {
            Iterator moreIter = moreBOTs.iterator();
            while (moreIter.hasNext()) {
                BlockOutTimeTO botTO = (BlockOutTimeTO) 
                                                    moreIter.next();
                if (! (blockOutTimeExists(botTO))) {
                    // add BlockOutTimeTO to collection
                    botTO.setNew();
                    blockOutTime.add(botTO);
                } else {
                    // BlockOutTimeTO already exists, cannot add
                    throw new BlockOutTimeException(...);
                }
            }
        } catch(Exception exception) {
            throw new EJBException(...);
        }
    }

    public void addSkillSet(Collection moreSkills) 
    throws SkillSetException {
        // similar to addBlockOutTime() implementation
        ...
    }

    ...

    public void updateBlockOutTime(Collection updBOTs) 
    throws BlockOutTimeException {
        try {
            Iterator botIter = blockOutTimes.iterator();
            Iterator updIter = updBOTs.iterator();
            while (updIter.hasNext()) {
                BlockOutTimeTO botTO = (BlockOutTimeTO)
                    updIter.next();
                while (botIter.hasNext()) {
                    BlockOutTimeTO existingBOT = 
                        (BlockOutTimeTO) botIter.next();
                    // compare key values to locate BlockOutTime
                    if (existingBOT.equals(botTO)) {
                        // Found BlockOutTime in collection
                        // replace old BlockOutTimeTO with new one
                        botTO.setDirty(); //modified old dependent
                        botTO.resetNew(); //not a new dependent
                        existingBOT = botTO;
                    }
                }
            }
        } catch (Exception exc) {
            throw new EJBException(...);
        }
    }

    public void updateSkillSet(Collection updSkills) 
    throws CommitmentException {
        // similar to updateBlockOutTime...
        ...
    }

    ...

}

[1]

See also[edit]

References[edit]

  1. ^ a b c d e f g "Core J2EE Patterns - Composite Entity". Oracle. Oracle. Retrieved 6 February 2016.
  2. ^ Johnson, R. (2003). Expert One-on-One J2EE Design and Development. Indianapolis: Wiley Publishing, Inc. p. 290.