To persist business data from Model instances, define the respective records as shared. These will have their values persisted in the database.
Each record and the relevant relationships are reflected in a database table. When you create a new instance of the record or relationship, a new entry is added to the respective table. The mapping of shared records to tables makes use of Hibernate as its ORM library.
Mapping of shared records to database occurs in accordance with the following rules:
Fetching of record instances is governed by Hibernate's principles with the transactions of the LSPS Server.
The revision history of shared Records, or auditing, relies on the Revision Entity that holds the revision ID and its timestamps: When an instance of an audited shared record changes, the Revision Entity calls the Revision Listener implemented by the LspsRevisionListener class. The listener creates a new revision instance with the revision data.
Important: Information on how to set up and use auditing and the related database schema is available in the Modeling guide.
Hence if you want to record custom revision information, you need to do the following:
Important: On WebSphere, it is not possible to implement a custom RevisionListener.
To create a custom Revision Entity with additional field so as to store additional revision information, do the following:
Override the newRevision(Object revisionEntity) method of the your RevisionListener class:
super.newRevision(revisionEntity);
((MapSharedRecordEntity) revisionEntity).set("USER", securityService.getPrincipalName());
An example implementation is here.
Important: Including complex logic in your Revision Listener class, such as, contacting an external system to acquire data, might result in performance issues.
To create a custom Revision Entity with a related share Record so as to add complex custom information to the revisions, do the following:
Create the related shared Record.
SharedRecordContext sharedRecordContext = SharedRecordContextProvider.INSTANCE.getSharedRecordContextByJndi(""); SharedRecordNamingInfo recordNamingInfo = sharedRecordContext.getNamingInfoForEntityName(((ExternalRecordEntity) revisionEntity).getEntityName());
recordNamingInfo = sharedRecordContext.getNamingInfoForTableName("<YOUR_RECORD_NAME>");
Important: Including complex logic in your Revision Listener class, such as, contacting an external system to acquire data, might result in performance issues.
In your data model, adjust the Entity Revision shared record to use your implementation and upload the resources.
Custom implementation of the RevisionListener must extend the LspsRevisionListener and implement EJBRevisionListener. Once you created your RevisionListener implementation make sure to register it in the ComponentServiceBean:
Example of a custom RevisionListener for a RevisionEntity record with a custom field user
import java.io.Serializable; import javax.annotation.security.PermitAll; import javax.ejb.EJB; import javax.ejb.Stateless; import org.hibernate.Session; import org.hibernate.envers.RevisionType; import com.whitestein.lsps.common.ejb.SecurityManagerServiceLocal; import com.whitestein.lsps.common.hibernate.SharedRecordContext; import com.whitestein.lsps.common.hibernate.SharedRecordContextProvider; import com.whitestein.lsps.common.hibernate.SharedRecordNamingInfo; import com.whitestein.lsps.common.hibernate.SharedRecordUtils; import com.whitestein.lsps.hibernate.envers.EJBRevisionListener; import com.whitestein.lsps.hibernate.envers.LspsRevisionListener; import com.whitestein.lsps.model.sharedrecord.ExternalRecordEntity; import com.whitestein.lsps.model.sharedrecord.MapSharedRecordEntity; @Stateless @PermitAll public class CustomRevisionListener extends LspsRevisionListener implements EJBRevisionListener {
//injects the security service (for the user field): @EJB private SecurityManagerServiceLocal securityService; @Override public void newRevision(Object revisionEntity) { super.newRevision(revisionEntity); //persisting into a custom field in the Revision Entity record: ((MapSharedRecordEntity) revisionEntity).set("USER", securityService.getPrincipalName()); } }
Example of a custom RevisionListener for a RevisionEntity record with the related record CustomRevisionData
import java.io.Serializable; import javax.annotation.security.PermitAll; import javax.ejb.EJB; import javax.ejb.Stateless; import org.hibernate.Session; import org.hibernate.envers.RevisionType; import com.whitestein.lsps.common.ejb.SecurityManagerServiceLocal; import com.whitestein.lsps.common.hibernate.SharedRecordContext; import com.whitestein.lsps.common.hibernate.SharedRecordContextProvider; import com.whitestein.lsps.common.hibernate.SharedRecordNamingInfo; import com.whitestein.lsps.common.hibernate.SharedRecordUtils; import com.whitestein.lsps.hibernate.envers.EJBRevisionListener; import com.whitestein.lsps.hibernate.envers.LspsRevisionListener; import com.whitestein.lsps.model.sharedrecord.ExternalRecordEntity; import com.whitestein.lsps.model.sharedrecord.MapSharedRecordEntity; @Stateless @PermitAll public class CustomRevisionListener extends LspsRevisionListener implements EJBRevisionListener {
//injects the security service (for the user field): @EJB private SecurityManagerServiceLocal securityService; @Override public void newRevision(Object revisionEntity) { super.newRevision(revisionEntity); //persisting into a record related to the Revision Entity record: //obtain the names of the for properties in the hibernate entity: //SharedRecordContext sharedRecordContext = SharedRecordContextProvider.INSTANCE.getSharedRecordContextByJndi(""); //SharedRecordNamingInfo recordNamingInfo = sharedRecordContext.getNamingInfoForEntityName(((ExternalRecordEntity) revisionEntity).getEntityName()); //obtain the name of the hibernate entity for your table: //recordNamingInfo = sharedRecordContext.getNamingInfoForTableName("CustomRevisionData"); MapSharedRecordEntity entity = new MapSharedRecordEntity("CustomRevisionData"); entity.set("NAME", "xxx"); Session session = SharedRecordUtils.getSessionFactory(null).getCurrentSession(); session.persist(entity); ((MapSharedRecordEntity) revisionEntity).set("S_CUSTOM_REVISION_ENTITY_CUSTOMREVISIONDATA", entity); } }
@EJB(beanName = "CustomRevisionListener") private EJBRevisionListener customRevisionListener; @Override protected void registerCustomComponents() { register(customRevisionListener, CustomRevisionListener.class); }