Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers
10g Release 3 (10.1.3.0) B25947-01 |
|
Previous |
Next |
When declarative defaulting falls short of your needs, you can perform programmatic defaulting in your entity object:
When an entity row is first created
When the entity row is first created or when refreshed to blank again
When the entity row is saved to the database
When an entity attribute value is set
The create()
method provides the entity object event you can handle to initialize default values the first time an entity row is created. Example 9-3 shows the overridden create method of the ServiceHistory
entity object in the SRDemo application. It calls the attribute setter methods to populate the SvhType
, CreatedBy
, and LineNo
attributes in a new service history entity row.
Example 9-3 Programmatically Defaulting Attribute Values for New Rows
// In ServiceHistoryImpl.java in SRDemo sample protected void create(AttributeList nameValuePair) { super.create(nameValuePair); setSvhType(getDefaultNoteType()); setCreatedBy(getCurrentUserId()); setLineNo(new Number(getServiceRequest().getMaxHistoryLineNumber()+1)); }
If an entity row has New
status and you call the refresh()
method on it, if you do not supply either the REFRESH_REMOVE_NEW_ROWS
or REFRESH_FORGET_NEW_ROWS
flag, then the entity row is returned to an Initialized
status. As part of this process, the entity object's initDefaults()
method is invoked, but not its create()
method again. So override the initDefaults()
method for programmatic defaulting logic that you want to fire both when the row is first created, as well as when it might be refreshed back to initialized status.
Section 6.6.3.7, "Synchronization with Trigger-Assigned Values" explained how to use the DBSequence
type for primary key attributes whose values need to be populated by a database sequence at commit time. Sometimes you may want to eagerly allocate a sequence number at entity row creation time so that the user can see its value and so that this value does not change when the data is saved. To accomplish this, use the SequenceImpl
helper class in the oracle.jbo.server
package in an overridden create()
method as shown in Example 9-4. It shows code from the custom Java class of the SRDemo application's Product
entity object. After calling super.create()
, it creates a new instance of the SequenceImpl
object, passing the sequence name and the current transaction object. Then it calls the setProdId()
attribute setter method with the return value from SequenceImpl
's getSequenceNumber()
method.
Example 9-4 Eagerly Defaulting an Attribute's Value from a Sequence at Create Time
// In ProductImpl.java import oracle.jbo.server.SequenceImpl; // Default ProdId value from PRODUCTS_SEQ sequence at entity row create time protected void create(AttributeList nameValuePair) { super.create(nameValuePair); SequenceImpl sequence = new SequenceImpl("PRODUCTS_SEQ",getDBTransaction()); setProdId(sequence.getSequenceNumber()); }
If you want to assign programmatic defaults for entity object attribute values before a row is saved, override the prepareForDML()
method and call the appropriate attribute setter methods to populate the derived attribute values. In order to perform the assignment only during INSERT
, UPDATE
, or DELETE
, you can compare the value of the operation
parameter passed to this method against the integer constants DML_INSERT
, DML_UPDATE
, DML_DELETE
respectively.
Example 9-5 shows the overridden prepareForDML()
method used by the ServiceHistory
entity object in the SRDemo application to automatically change the status of a service request when a service history note of certain types are created. When a new service history entry is inserted, this code changes the status of:
A pending or closed service request to open if the new history note is added by a customer
An open service request to pending if the new history note is added by a technician
Example 9-5 Assigning Derived Values Before Saving Using PrepareForDML
// In ServiceHistoryImpl.java protected void prepareForDML(int operation, TransactionEvent e) { super.prepareForDML(operation, e); // If we are inserting a new service history entry... if (operation == DML_INSERT) { ServiceRequestImpl serviceReq = getServiceRequest(); String historyType = getSvhType(); // If request is pending or closed and customer adds note, status => Open if ((serviceReq.isPending() || serviceReq.isClosed()) && CUSTOMER_TYPE.equals(historyType)) { serviceReq.setOpen(); } // If request is open & technician adds a non-hidden note, status => Pending if (serviceReq.isOpen() && TECHNICIAN_TYPE.equals(historyType)) { serviceReq.setPending(); } } }
To assign derived attribute values whenever another attribute's value is set, add code to the latter attribute's setter method. Example 9-6 shows the setter method for the AssignedTo
attribute in the SRDemo application's ServiceRequest
entity object. After the call to setAttributeInternal()
to set the value of the AssignedTo
attribute, it uses the setter method for the AssignedDate
attribute to set its value to the current date and time.
Example 9-6 Setting the Assigned Date Whenever the AssignedTo Attribute Changes
// In ServiceRequestImpl.java public void setAssignedTo(Number value) { setAttributeInternal(ASSIGNEDTO, value); setAssignedDate(getCurrentDateWithTime()); }
Note: It is safe to add custom code to the generated attribute getter and setter methods as shown here. When JDeveloper modifies code in your class, it intelligently leaves your custom code in place. |