Upgrade Process for Service Builder in Liferay 7/DXP
Introduction
Liferay provides a code generation tool called Service Builder that will create the service and persistence layer. Liferay service builder uses the spring framework for providing service layer implementation and hibernate framework for the persistence layer. Service Builder takes an XML file as an input and generates the model, persistence, and service layers for our application. It will also create a related entity in the database as well. If you want to update an entity then you just need to update the XML file and rebuild serviceBuilder and it will update both code as well as the database.
From Liferay DXP, it’s not that much easy to update entity once it will be created. For example, if you created a custom entity using service-builder and now if you want to alter any column in an existing entity then it will not reflect in the database. Although service builder will update the service and persistence layer. Often developers raises an issue that Service-builder is not updating the database.
Today I’ll show you how can you update the database after updating any custom entity.
During the development phase If you want to apply the new changes quickly then, LR recommended below SQL operations on the database. After executing below SQL operations if you re-build and deploy your service builder then it will reflect latest changes into the database as well.
drop table relating to the service;
delete the record on the release_ table which is related to the service;
delete the record on the servicecomponent table which is related to the service;
Note: These steps are only recommended during development phase. If you want to update an entity in PROD then you should perform the upgrade process.
Step 1: Implement Upgrade Process to Add New Column
- First we will create an upgrade process which will be responsible to add a new column in the database.
- We need to extend LRs UpgradeProcess and also need to implement it’s override method.
public class AddColumnUpgradeProcess extends UpgradeProcess {
public AddColumnUpgradeProcess(Class entityClass, String tableName, String columnName, String columnType) {
_entityClass = entityClass;
_tableName = tableName;
_columnName = columnName;
_columnType = columnType;
}
@Override
protected void doUpgrade() throws Exception {
_addColumn();
}
private void _addColumn() throws Exception {
_logUtil.logInfo("Adding column ", _columnName, " to table ", _tableName);
if (!hasColumn(_tableName, _columnName)) {
alter(_entityClass, new AlterTableAddColumn(_columnName + StringPool.SPACE + _columnType));
}
else {
_logUtil.logInfo("Column ", _columnName, " already exists on table ", _tableName);
}
}
private static final LogUtil _logUtil = new LogUtil(AddColumnUpgradeProcess.class);
private final String _columnName;
private final String _columnType;
private final Class _entityClass;
private final String _tableName;
}
Step 2: Override Register Method
- You need to override an abstract method called register of the UpgradeStepRegistrator interface.
@Override
public void register(UpgradeStepRegistrator.Registry registry) {
}
Step 3: Register new version of an entity
- In the overridden register method we need to add new version of an entity so that whenever our module will deploy it will execute logic implemented in latest register method.
- Here I’ve created a new column type of String called ‘dealType’ in an existing Deal table.
- After successful deployment of this module it will upgrade the schema version from 1.0.0 to 1.0.1.
registry.register(_BUNDLE_NAME, _SCHEMA_VERSION_1_0_0, _SCHEMA_VERSION_1_0_1,
new SchemaAddColumnUpgradeProcess(
DealModelImpl.class, DealModelImpl.TABLE_NAME, "dealType", "STRING"));
Step 4: Update bnd.bnd file
- In your module’s bnd.bnd file, specify a Liferay-Require-SchemaVersion header with the new schema version value. Here we have updated schema version from 1.0.0 to 1.0.1.
Liferay-Require-SchemaVersion: 1.0.1
Step 5: Update service.xml file
- Above steps will only add a new column in database. You still need to update your service.xml file to update persistence and model layer of your custom entity respectively.
That’s it using the above steps you will be able to add a new column in your existing created table.
Note: If you want to add a new entity in your existing service builder then you can implement the upgrade process which will run SQL file from specified folder perform operations based on that file. For that, you can use runSQLTemplateString(String template, boolean evaluate, boolean failOnError) method of LR’s BaseDBProcess class in doUpgrade method.