2.1 to 3.0 Migration

Broadleaf Commerce version 3.0 represents a huge step forward in our technology and approach. As such, various changes are required to existing version 2.1 installations in order to prepare them to take advantage of the new 3.0 features. Please read this migration document carefully, as it outlines in detail the required migration steps. It also calls out areas of consideration depending on the degree to which you've customized your Broadleaf Commerce installation. Use these instructions at your own risk. Make sure to backup your data before attempting any migration and always test in a development environment before executing in production.

Make sure the ant.hibernate.sql.ddl.dialect value in build.properties is the correct dialect for your target schema. Change if required.

Item: Replace the build-sql task in site/build.xml

Delete the <target name="build-sql"> element, as it is out-of-date

Add the following to build.xml

<targetname="build-create-sql"><!-- You will need to run a mvn install on your project before attempting to execute this task. Also, you will likely need to assign additional heap space to your ANT process. A setting of -XX:MaxPermSize=256M -Xmx512M should be sufficient. This can be done by populating the 'ANT_OPTS' environment variable: export ANT_OPTS=-XX:MaxPermSize=256M -Xmx512M which will ensure those settings for all ant processes. Alternatively you could use JAVA_OPTS which is for the global JVM and will effect all Java processes. --><mkdirdir="target/sql/create"/><artifact:pomid="myPom"file="pom.xml"/><artifact:dependenciesfilesetId="pomDeps"pomRefId="myPom"useScope="compile"/><propertyname="baseTarget"location="target/${myPom.build.finalName}/WEB-INF"/><filesetid="libDir"dir="${baseTarget}/lib"/><pathid="build.runtime.classpath"><!--There are some additional libraries needed at compile time that are not included in WEB-INF/lib - find those libraries via a difference algorithm--><restrict><difference><filesetrefid="pomDeps"/><intersect><filesetrefid="pomDeps"/><filesetrefid="libDir"/></intersect></difference><rsel:not><rsel:namename="**/*.pom"/></rsel:not></restrict><!--Add the lib directory to get all the dependencies required for the demo app--><filesetrefid="libDir"/><dirsetdir="src/main/resources"/><!--Add the classes directory in the war project, if required--><!--<pathelement location="${baseTarget}/classes"/>--></path><!--If the war project does not contain custom entities (best practice), then it is not necessary to include application context from the WEB-INF directory--><!--<property name="my.app.context" location="src/main/webapp/WEB-INF/applicationContext.xml"/>--><taskdefname="hibernatetool"classname="org.broadleafcommerce.common.util.sql.HibernateToolTask"classpathref="build.runtime.classpath"/><hibernatetooldestDir="target/sql/create"combinePersistenceUnits="false"refineFileNames="true"><!--add in additional persistence configuration related to the cms --><classPathApplicationContextpath="bl-cms-contentClient-applicationContext.xml"/><classPathApplicationContextpath="bl-open-admin-contentClient-applicationContext.xml"/><!--add in additional persistence configuration for our core --><classPathApplicationContextpath="applicationContext.xml"/><!--see description for my.app.context above --><fileSystemApplicationContextpath="src/main/webapp/WEB-INF/applicationContext.xml"/><classPathApplicationContextpath="bl-fake-applicationContext-ant.xml"/><!--select the dialects and persistence units to export--><jpaconfigurationpersistenceUnit="blPU"dialect="${ant.hibernate.sql.ddl.dialect}"/><jpaconfigurationpersistenceUnit="blSecurePU"dialect="${ant.hibernate.sql.ddl.dialect}"/><jpaconfigurationpersistenceUnit="blCMSStorage"dialect="${ant.hibernate.sql.ddl.dialect}"/><!--other required elements--><classpathrefid="build.runtime.classpath"/><hbm2ddlexport="false"update="false"create="true"/></hibernatetool></target><targetname="build-update-sql"><!-- You will need to run a mvn install on your project before attempting to execute this task. Also, you will likely need to assign additional heap space to your ANT process. A setting of -XX:MaxPermSize=256M -Xmx512M should be sufficient. This can be done by populating the 'ANT_OPTS' environment variable: export ANT_OPTS=-XX:MaxPermSize=256M -Xmx512M which will ensure those settings for all ant processes. Alternatively you could use JAVA_OPTS which is for the global JVM and will effect all Java processes. --><mkdirdir="target/sql/update"/><artifact:pomid="myPom"file="pom.xml"/><artifact:dependenciesfilesetId="pomDeps"pomRefId="myPom"useScope="compile"/><propertyname="baseTarget"location="target/${myPom.build.finalName}/WEB-INF"/><filesetid="libDir"dir="${baseTarget}/lib"/><pathid="build.runtime.classpath"><!--There are some additional libraries needed at compile time that are not included in WEB-INF/lib - find those libraries via a difference algorithm--><restrict><difference><filesetrefid="pomDeps"/><intersect><filesetrefid="pomDeps"/><filesetrefid="libDir"/></intersect></difference><rsel:not><rsel:namename="**/*.pom"/></rsel:not></restrict><!--Add the lib directory to get all the dependencies required for the demo app--><filesetrefid="libDir"/><dirsetdir="src/main/resources"/><!--Add the classes directory in the war project, if required--><!--<pathelement location="${baseTarget}/classes"/>--></path><!--If the war project does not contain custom entities (best practice), then it is not necessary to include application context from the WEB-INF directory--><!--<property name="my.app.context" location="src/main/webapp/WEB-INF/applicationContext.xml"/>--><taskdefname="hibernatetool"classname="org.broadleafcommerce.common.util.sql.HibernateToolTask"classpathref="build.runtime.classpath"/><hibernatetooldestDir="target/sql/update"combinePersistenceUnits="false"refineFileNames="true"><!--add in additional persistence configuration related to the cms --><classPathApplicationContextpath="bl-cms-contentClient-applicationContext.xml"/><classPathApplicationContextpath="bl-open-admin-contentClient-applicationContext.xml"/><!--add in additional persistence configuration for our core --><classPathApplicationContextpath="applicationContext.xml"/><!--see description for my.app.context above --><fileSystemApplicationContextpath="src/main/webapp/WEB-INF/applicationContext.xml"/><classPathApplicationContextpath="bl-fake-applicationContext-ant.xml"/><!--select the dialects and persistence units to export--><jpaconfigurationpersistenceUnit="blPU"dialect="${ant.hibernate.sql.ddl.dialect}"url="${ant.blPU.url}"userName="${ant.blPU.userName}"password="${ant.blPU.password}"driverClassName="${ant.blPU.driverClassName}"/><jpaconfigurationpersistenceUnit="blSecurePU"dialect="${ant.hibernate.sql.ddl.dialect}"url="${ant.blSecurePU.url}"userName="${ant.blSecurePU.userName}"password="${ant.blSecurePU.password}"driverClassName="${ant.blSecurePU.driverClassName}"/><jpaconfigurationpersistenceUnit="blCMSStorage"dialect="${ant.hibernate.sql.ddl.dialect}"url="${ant.blCMSStorage.url}"userName="${ant.blCMSStorage.userName}"password="${ant.blCMSStorage.password}"driverClassName="${ant.blCMSStorage.driverClassName}"/><!--other required elements--><classpathrefid="build.runtime.classpath"/><hbm2ddlexport="false"update="true"create="false"/></hibernatetool></target>

Item: Update your current 2.1 database schema to be 3.0 compliant

Via ANT, execute the "build-update-sql" task in site/build.xml (will take a few minutes to run)

This task should launch a lightweight version of Broadleaf's domain and your domain extensions

A comparison is performed against this combined domain and the target schema

The result of this comparison is an update sql file that can be run against your existing schema to alter its structure to be 3.0 compliant

The most straightforward approach is to remove old information and repopulate

If you've done a lot of role customization for admin users, then this section will require some diligence, as you will need to manually rebuild your associations between roles and permissions. You may want to record the permissions you have associated with each role (see your BLC_ADMIN_ROLE_PERMISSION_XREF table) so that you can recreate these with the repopulated information.

Refer to the following table of standard roles and required permissions in 3.0. This can be used as a guide.

Role Name

Permission Name

ROLE_CONTENT_APPROVER

PERMISSION_ALL_APPROVER_SANDBOX

ROLE_CONTENT_APPROVER

PERMISSION_ALL_STRUCTURED_CONTENT

ROLE_CONTENT_APPROVER

PERMISSION_ALL_ASSET

ROLE_CONTENT_APPROVER

PERMISSION_ALL_PAGE

ROLE_CONTENT_APPROVER

PERMISSION_OTHER_DEFAULT

ROLE_CONTENT_EDITOR

PERMISSION_ALL_USER_SANDBOX

ROLE_CONTENT_EDITOR

PERMISSION_ALL_STRUCTURED_CONTENT

ROLE_CONTENT_EDITOR

PERMISSION_ALL_ASSET

ROLE_CONTENT_EDITOR

PERMISSION_ALL_PAGE

ROLE_CONTENT_EDITOR

PERMISSION_OTHER_DEFAULT

ROLE_CUSTOMER_SERVICE_REP

PERMISSION_ALL_CUSTOMER

ROLE_CUSTOMER_SERVICE_REP

PERMISSION_ALL_ORDER_ITEM

ROLE_CUSTOMER_SERVICE_REP

PERMISSION_ALL_FULFILLMENT_GROUP

ROLE_CUSTOMER_SERVICE_REP

PERMISSION_ALL_ORDER

ROLE_CUSTOMER_SERVICE_REP

PERMISSION_OTHER_DEFAULT

ROLE_PROMOTION_MANAGER

PERMISSION_ALL_PROMOTION

ROLE_PROMOTION_MANAGER

PERMISSION_OTHER_DEFAULT

ROLE_MERCHANDISE_MANAGER

PERMISSION_ALL_CURRENCY

ROLE_MERCHANDISE_MANAGER

PERMISSION_ALL_SEARCHFACET

ROLE_MERCHANDISE_MANAGER

PERMISSION_ALL_ASSET

ROLE_MERCHANDISE_MANAGER

PERMISSION_ALL_SKU

ROLE_MERCHANDISE_MANAGER

PERMISSION_ALL_PRODUCT_OPTION

ROLE_MERCHANDISE_MANAGER

PERMISSION_ALL_PRODUCT

ROLE_MERCHANDISE_MANAGER

PERMISSION_ALL_CATEGORY

ROLE_MERCHANDISE_MANAGER

PERMISSION_OTHER_DEFAULT

ROLE_ADMIN

PERMISSION_ALL_MODULECONFIGURATION

ROLE_ADMIN

PERMISSION_ALL_CURRENCY

ROLE_ADMIN

PERMISSION_ALL_SEARCHFACET

ROLE_ADMIN

PERMISSION_ALL_SEARCHREDIRECT

ROLE_ADMIN

PERMISSION_ALL_URLHANDLER

ROLE_ADMIN

PERMISSION_ALL_ADMIN_USER

ROLE_ADMIN

PERMISSION_ALL_APPROVER_SANDBOX

ROLE_ADMIN

PERMISSION_ALL_USER_SANDBOX

ROLE_ADMIN

PERMISSION_ALL_STRUCTURED_CONTENT

ROLE_ADMIN

PERMISSION_ALL_ASSET

ROLE_ADMIN

PERMISSION_ALL_PAGE

ROLE_ADMIN

PERMISSION_ALL_CUSTOMER

ROLE_ADMIN

PERMISSION_ALL_ORDER_ITEM

ROLE_ADMIN

PERMISSION_ALL_FULFILLMENT_GROUP

ROLE_ADMIN

PERMISSION_ALL_ORDER

ROLE_ADMIN

PERMISSION_ALL_PROMOTION

ROLE_ADMIN

PERMISSION_ALL_SKU

ROLE_ADMIN

PERMISSION_ALL_PRODUCT_OPTION

ROLE_ADMIN

PERMISSION_ALL_PRODUCT

ROLE_ADMIN

PERMISSION_ALL_CATEGORY

ROLE_ADMIN

PERMISSION_OTHER_DEFAULT

Clear out the BLC_ADMIN_ROLE_PERMISSION_XREF table to avoid constraint violations during the next steps

Clear out the BLC_ADMIN_PERMISSION_ENTITY table so that new values can be imported

Clear out the BLC_ADMIN_PERMISSION table so that new values can be imported

If you have NOT altered any roles and took advantage of the roles from the 2.1 demo starter project, you can execute the following in your favorite sql execution environment to rebuild the BLC_ADMIN_ROLE_PERMISSION_XREF table.

If you are using MySql as your database platform, you'll need to check how boolean fields are represented. Review the structure of your current BLC_ADDRESS table. If the IS_ACTIVE column is of type BIT, then you are using the old way of representing boolean fields in MySql. If the type is TINYINT, then you can ignore this item.

If your boolean columns are represented as BIT, then you have 2 choices for Broadleaf 3.0 compatibility:

You can convert all boolean field columns in your Broadleaf database schema from BIT to TINYINT, OR

You can use org.broadleafcommerce.common.dialect.Broadleaf2CompatibilityMySQL5InnoDBDialect as your Hibernate dialect (this custom dialect takes care of referencing boolean fields as type BIT, rather than TINYINT)

There are no known issues with PostgreSql, Sql Server or Oracle.

Item: Make sure locale settings are up-to-date

Review the contents of the BLC_LOCALE table. One of the locales should be marked as default.

Make sure the default locale is your desired locale, as this can impact price display on your site

For example, if en is the default locale, you may want to add a new locale with code en_US for US English and make it the default instead.

Item: Make sure existing orders are compatible

Add a value to the LOCALE_CODE column for all orders in the BLC_ORDER table. For example, use en_US for US English.

Item: Property file updates

Remove the use.jrebel.compatibility.mode property as it is no longer used.

Add thymeleaf.view.resolver.cache=true to common-shared.properties and thymeleaf.view.resolver.cache=false to development-shared.properties

Considerations

GWT has been phased out and is no longer supported for admin UI/functionality customization.

Logical portions of the admin are broken up into Modules, which themselves contains sections.

Modules are represented in the BLC_ADMIN_MODULE table and sections are represented in the BLC_ADMIN_SECTION table.

@AdminPresentation annotations in the Broadleaf domain classes support most of the functionality observed in the admin.

For simple extended properties, it's possible that you're entity extensions may work as they are in the new admin without any additional @AdminPresentation annotation tweaking.

For collection/map fields in your entity extensions, you will need to use one of the admin presentation collection annotations. Refer to the source code for ProductImpl for a variety of concrete usage examples.

Spring MVC is employed to drive most of the plumbing - specialized controllers can be used to achieve specific results (e.g. see AdminOrderController in the Broadleaf source).

Order Pricing Considerations

In previous releases, it was possible for order items to be split in the order when promotions were applied. This generally occurred as the result of a Buy-One-Get-One-Free promotion where only part of the total quantity for an item qualified for a discount. In such a case, a new discounted Order Item was created with the smaller quantity and the quantity for the regularly priced item was decremented - essentially "splitting" the item.

The "splitting" practice was error prone, as various parts of the order had to be update to compensate for the split (e.g. fulfillment group items had to be updated).

In version 3.0, we have done away with the Order Item splitting concept in favor of OrderItemPriceDetails.

OrderItemPriceDetails allows a single order item to have multiple prices for multiple quantities. This solves the requirement for discounting several of an order item's quantity, while not changing the quantity of the order item itself.

As a result, a call to OrderItem.getPrice() now returns an average of the price details for an item.

Depending on how order item pricing is displayed on your site, this change could have an impact on what your users see and your site should be thoroughly tested after the upgrade as a result.

Offer Considerations

The MVEL generated for offers in version 2.1 may be incompatible with the new 3.0 rule builder UI.

Incompatible rules will still function in the system, but will be displayed in the admin page as immutable,raw MVEL.

If you wish to change the rules for an incompatible offer, you'll need to disable the incompatible offer and create a new offer that matches your desired rules and configuration.

Please note that this migration documentation is to be used as a guide in migrating any generic Broadleaf Commerce application to version 3.0. We do not cover things that we might have changed in our starter Heat Clinic project, such as miscellaneous CSS updates, etc. For example, to take advantage of the PhoneImpl Java class, we changed the Heat Clinic checkout's billingInfoForm.html. These kinds of specialized changes in our sample application are not covered as part of this guide.

If you would like to see an absolutely comprehensive list of all changes that were made to our sample application between 2.1 and 3.0, you can utilize this GitHub branch compare link.