Documentation Home

2.2 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.2 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.

Migration Steps

Maven updates

Item: Update the root pom.xml (sample file)

  1. While it may be introduced again in the future, the combined module is not currently supported in 3.0.

    • In the root pom.xml, remove the line <module>combined</module> from the "modules" element.
  2. Change the blc.version element to 3.0.0-SNAPSHOT

    <blc.version>3.0.0-SNAPSHOT</blc.version>

  3. Remove the gwt.version element (phased out)

    <gwt.version>2.4.0</gwt.version>

  4. If not present already, add a public snapshots repository to retrieve BLC snapshot builds.

    <repositories>
        <repository>
            <id>public snapshots</id>
            <name>public snapshots</name>
            <url>http://nexus.broadleafcommerce.org/nexus/content/repositories/snapshots/</url>
        </repository>
    </repositories>
    
  5. Update jrebel plugin dependency

    • change all instances of <artifactId>javarebel-maven-plugin</artifactId> to <artifactId>jrebel-maven-plugin</artifactId>
    • change the jrebel plugin version to 1.1.3

    Note: This may already be configured, depending on which 2.2 DemoSite you based your project on

  6. Remove gwt maven plugin config (phased out)

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>gwt-maven-plugin</artifactId>
        <version>${gwt.version}</version>
    </plugin>
    
  7. Remove the following unwanted, or unnecessary dependency elements

    • groupId: com.google.gwt / artifactId: gwt-user
    • groupId: org.hibernate / artifactId: hibernate-validator-annotation-processor
    • groupId: javax.validation / artifactId: validation-api

Item: Update admin/pom.xml (sample file)

  1. Remove the following unwanted, or unnecessary plugins

    • groupId: org.apache.maven.plugins / artifactId: maven-source-plugin
    • groupId: org.codehaus.mojo / artifactId: gwt-maven-plugin
    • groupId: org.apache.maven.plugins / artifactId: maven-clean-plugin
  2. Remove the following unwanted, or unnecessary profiles

    • id: gwt-jrebel
    • id: full-clean
  3. Remove the following unwanted, or unnecessary dependency elements

    • groupId: org.hibernate / artifactId: hibernate-validator-annotation-processor
    • groupId: javax.validation / artifactId: validation-api
  4. Update jrebel plugin dependency

    • change all instances of <artifactId>javarebel-maven-plugin</artifactId> to <artifactId>jrebel-maven-plugin</artifactId>

    Note: This may already be configured, depending on which 2.2 DemoSite you based your project on

  5. Add additional lines to the configuration block of the jetty-maven-plugin:

    <webAppConfig>
        <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
    </webAppConfig>
    

Item: Update site/pom.xml (sample file)

  1. Update jrebel plugin dependency

    • change all instances of <artifactId>javarebel-maven-plugin</artifactId> to <artifactId>jrebel-maven-plugin</artifactId>

    Note: This may already be configured, depending on which 2.2 DemoSite you based your project on

  2. Add additional lines to the configuration block of the jetty-maven-plugin:

    <webAppConfig>
        <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
    </webAppConfig>
    

Item: Update core/pom.xml (sample file)

  1. Update jrebel plugin dependency

    • change all instances of <artifactId>javarebel-maven-plugin</artifactId> to <artifactId>jrebel-maven-plugin</artifactId>

    Note: This may already be configured, depending on which 2.2 DemoSite you based your project on


Web.xml updates

Item: Update site/src/main/webapp/WEB-INF/web.xml (sample file)

  1. Remove the following <filter> definitions, as they are now declared in applicationContext-filter.xml

    • filter-name: blPreSecurityFilterChain
    • filter-name: blPostSecurityFilterChain
  2. Remove the following <filter-mapping> definitions as well

    • filter-name: blPreSecurityFilterChain
    • filter-name: blPostSecurityFilterChain

Item: Update admin/src/main/webapp/WEB-INF/web.xml (sample file)

  1. Remove the following <filter> definitions, as they are now declared in applicationContext-filter.xml

    • filter-name: blPreSecurityFilterChain
    • filter-name: blPostSecurityFilterChain
  2. Remove the following <filter-mapping>. definitions as well

    • filter-name: blPreSecurityFilterChain
    • filter-name: blPostSecurityFilterChain
  3. Add the following listener if it's not already present

    <listener>
        <listener-class>
             org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    

Application Context Updates

Item: Update all applicationContext*.xml files

  1. Look in site/src/main/webapp/WEB-INF, admin/src/main/webapp/WEB-INF and core/src/main/resources

  2. Change all spring schemaLocation attribute values to point to 3.2 (e.g. spring-jee-3.1.xsd should point to spring-jee-3.2.xsd)

    • Except for spring-security-3.1.xsd, which should be left at version 3.1

Item: Update site/src/main/webapp/WEB-INF/applicationContext.xml (sample file)

  1. Remove beans with ids "resourceBundleExtensionPoint" and "messageSource"

  2. Add externalized string support by including the "messageSource" bean:

    <bean id="messageSource" class="org.broadleafcommerce.common.util.BroadleafMergeResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>classpath:messages</value>
            </list>
        </property>
    </bean>
    
  3. Add image thumbnail support:

    <bean id="blStaticMapNamedOperationComponent" class="org.broadleafcommerce.cms.file.service.operation.StaticMapNamedOperationComponent">
        <property name="namedOperations">
            <map>
                <entry key="browse">
                    <map>
                        <entry key="resize-width-amount" value="400"/>
                        <entry key="resize-height-amount" value="400"/>
                        <entry key="resize-high-quality" value="false"/>
                        <entry key="resize-maintain-aspect-ratio" value="true"/>
                        <entry key="resize-reduce-only" value="true"/>
                    </map>
                </entry>
                <entry key="thumbnail">
                    <map>
                        <entry key="resize-width-amount" value="60"/>
                        <entry key="resize-height-amount" value="60"/>
                        <entry key="resize-high-quality" value="false"/>
                        <entry key="resize-maintain-aspect-ratio" value="true"/>
                        <entry key="resize-reduce-only" value="true"/>
                    </map>
                </entry>
            </map>
        </property>
    </bean>
    

Item: Update site/src/main/webapp/WEB-INF/applicationContext-security.xml (sample file)

  1. Remove the <sec:custom-filter ref="blCartStateFilter" before="ANONYMOUS_FILTER"/> element

  2. Add the following filters in the <sec:http> element:

    <sec:custom-filter ref="blPreSecurityFilterChain" before="CHANNEL_FILTER"/>
    <sec:custom-filter ref="blPostSecurityFilterChain" after="SWITCH_USER_FILTER"/>
    

Item: Update site/src/main/webapp/WEB-INF/applicationContext-servlet.xml (sample file)

  1. Remove the <mvc:resources> elements for location="/js/" and location="/css/"

  2. Add new beans for the bundling-capable resource handler:

    <bean id="blJsResources" class="org.broadleafcommerce.common.web.resource.BroadleafResourceHttpRequestHandler">
        <property name="locations">
            <list>
                <value>/js/</value>
                <value>classpath:/common_js/</value>
            </list>
        </property>
    </bean>
    
    <bean id="blCssResources" class="org.broadleafcommerce.common.web.resource.BroadleafResourceHttpRequestHandler">
        <property name="locations">
            <list>
                <value>/css/</value>
            </list>
        </property>
    </bean>
    
    <!-- Map various location URLs to our resource handlers -->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="order" value="-10" />
        <property name="mappings">
            <props>
                <prop key="/js/**">blJsResources</prop>
                <prop key="/css/**">blCssResources</prop>
            </props>
        </property>
    </bean>
    

Item: Replace site/src/main/webapp/WEB-INF/applicationContext-filter.xml with the new version

  1. Download from https://github.com/BroadleafCommerce/DemoSite/blob/broadleaf-3.0.0-GA/site/src/main/webapp/WEB-INF/applicationContext-filter.xml

Item: Update admin/src/main/webapp/WEB-INF/applicationContext-admin.xml (sample file)

  1. Remove beans with ids "resourceBundleExtensionPoint" and "messageSource"

  2. Add externalized string support by including the "messageSource" bean:

    <bean id="messageSource" class="org.broadleafcommerce.common.util.BroadleafMergeResourceBundleMessageSource">
        <property name="useCodeAsDefaultMessage" value="${messages.useCodeAsDefaultMessage}" />
        <property name="cacheSeconds" value="${messages.cacheSeconds}" />
        <property name="basenames">
            <list>
                <value>classpath:messages-admin</value>
            </list>
        </property>
    </bean>
    
  3. Add additionally required bundle files to the JavaScript bundle:

    <bean id="blResourceBundlingService" class="org.broadleafcommerce.common.resource.service.ResourceBundlingServiceImpl">
        <property name="additionalBundleFiles">
            <map>
                <entry key="admin.js">
                    <list>
                        <value>admin/catalog/product.js</value>
                        <value>admin/catalog/offer.js</value>
                        <value>admin/catalog/category.js</value>
                    </list>
                </entry>
            </map>
        </property>
    </bean>
    

Item: Update admin/src/main/webapp/WEB-INF/applicationContext-admin-security.xml (sample file)

  1. Replace <sec:http> elements for ignoring security for static elements and "forgot password" flows. Use the following:

    <sec:http pattern="/**/*.css" security="none" />
    <sec:http pattern="/**/*.js" security="none" />
    <sec:http pattern="/img/**" security="none" />
    <sec:http pattern="/favicon.ico" security="none" />
    <sec:http pattern="/robots.txt" security="none" />
    <sec:http pattern="/login" security="none" />
    <sec:http pattern="/forgotUsername" security="none" />
    <sec:http pattern="/forgotPassword" security="none" />
    <sec:http pattern="/changePassword" security="none" />
    <sec:http pattern="/resetPassword" security="none" />
    <sec:http pattern="/sendResetPassword" security="none" />
    
  2. Update the main <sec:http> element filters to include the following:

    <sec:custom-filter ref="blPreSecurityFilterChain" before="CHANNEL_FILTER"/>
    <sec:custom-filter ref="blCsrfFilter" before="FORM_LOGIN_FILTER"/>
    <sec:custom-filter ref="blPostSecurityFilterChain" after="SWITCH_USER_FILTER"/>
    
  3. Update the <sec:intercept-url> elements for "blAdminFilterSecurityInterceptor" to the following. The patterns have changed.

    <sec:intercept-url pattern="/**/*" access="PERMISSION_OTHER_DEFAULT" />
    <sec:intercept-url pattern="/*" access="PERMISSION_OTHER_DEFAULT" />
    
  4. Replace the "blAdminAuthenticationFailureHandler" bean with the following.

    <bean id="blAdminAuthenticationFailureHandler" class="org.broadleafcommerce.openadmin.security.BroadleafAdminAuthenticationFailureHandler">
        <constructor-arg value="/login?login_error=true" />
    </bean>
    
  5. Replace the "blAdminAuthenticationSuccessHandler" bean with the following.

    <bean id="blAdminAuthenticationSuccessHandler" class="org.broadleafcommerce.openadmin.security.BroadleafAdminAuthenticationSuccessHandler">
        <property name="defaultTargetUrl" value="/loginSuccess"/>
        <property name="alwaysUseDefaultTargetUrl" value="false"/>
    </bean>
    
  6. Add the following bean

    <bean id="blCsrfFilter" class="org.broadleafcommerce.common.security.handler.CsrfFilter" />
    
  7. Change the <sec:password-encoder> bean to utilize the blAdminPasswordEncoder bean:

    <sec:password-encoder ref="blAdminPasswordEncoder" />
    

Item: Replace admin/src/main/webapp/WEB-INF/applicationContext-servlet-admin.xml

  1. Download from https://github.com/BroadleafCommerce/DemoSite/blob/broadleaf-3.0.0-GA/admin/src/main/webapp/WEB-INF/applicationContext-servlet-admin.xml

  2. Replace admin/src/main/webapp/WEB-INF/applicationContext-servlet-admin.xml with the downloaded file


Item: Replace admin/src/main/webapp/WEB-INF/applicationContext-admin-filter.xml with the new version

  1. Download from https://github.com/BroadleafCommerce/DemoSite/blob/broadleaf-3.0.0-GA/admin/src/main/webapp/WEB-INF/applicationContext-admin-filter.xml

Other Updates

Item: A custom AdminLoginController (extends BroadleafAdminLoginController) is no longer required. Remove such a class if you've implemented one.

Item: A custom AdminModulesController (extends BroadleafAdminModulesController) is no longer required. Remove such a class if you've implemented one.

Item: Update Solr configuration (if using Solr search)

  1. Update site/resources/schema.xml

  2. If you have customized Solr indexing configuration, then review your changes before performing any update here

  3. Replace the <fields> element with the following:

    <fields>
        <field name="namespace" type="string" indexed="true" stored="false" />
        <field name="id" type="string" indexed="true" stored="true" />
        <field name="productId" type="long" indexed="true" stored="true" />
        <field name="category" type="long" indexed="true" stored="false" multiValued="true" />
        <field name="explicitCategory" type="long" indexed="true" stored="false" multiValued="true" />
        <field name="searchable" type="text_general" indexed="true" stored="false" />
        <dynamicField name="*_searchable" type="text_general" indexed="true" stored="false" />
    
        <dynamicField name="*_i" type="int" indexed="true" stored="false" />
        <dynamicField name="*_is" type="int" indexed="true" stored="false" multiValued="true" />
        <dynamicField name="*_s" type="string" indexed="true" stored="false" />
        <dynamicField name="*_ss" type="string" indexed="true" stored="false" multiValued="true" />
        <dynamicField name="*_l" type="long" indexed="true" stored="false" />
        <dynamicField name="*_ls" type="long" indexed="true" stored="false" multiValued="true" />
        <dynamicField name="*_t" type="text_general" indexed="true" stored="false" />
        <dynamicField name="*_txt" type="text_general" indexed="true" stored="false" multiValued="true" />
        <dynamicField name="*_b" type="boolean" indexed="true" stored="false" />
        <dynamicField name="*_bs" type="boolean" indexed="true" stored="false" multiValued="true" />
        <dynamicField name="*_d" type="double" indexed="true" stored="false" />
        <dynamicField name="*_ds" type="double" indexed="true" stored="false" multiValued="true" />
        <dynamicField name="*_p" type="double" indexed="true" stored="false" />
    
        <dynamicField name="*_dt" type="date" indexed="true" stored="false" />
        <dynamicField name="*_dts" type="date" indexed="true" stored="false" multiValued="true" />
    
        <!-- some trie-coded dynamic fields for faster range queries -->
        <dynamicField name="*_ti" type="tint" indexed="true" stored="false" />
        <dynamicField name="*_tl" type="tlong" indexed="true" stored="false" />
        <dynamicField name="*_td" type="tdouble" indexed="true" stored="false" />
        <dynamicField name="*_tdt" type="tdate" indexed="true" stored="false" />
    </fields>
    

Data Migration

Item: Update build.properties

  1. Add database connection information to build.properties (change to fit your environment)

    ant.blPU.url=jdbc:mysql://localhost:3306/broadleafcommerce_20
    ant.blPU.userName=root
    ant.blPU.password=
    ant.blPU.driverClassName=com.mysql.jdbc.Driver
    
    ant.blSecurePU.url=jdbc:mysql://localhost:3306/broadleafcommerce_20
    ant.blSecurePU.userName=root
    ant.blSecurePU.password=
    ant.blSecurePU.driverClassName=com.mysql.jdbc.Driver
    
    ant.blCMSStorage.url=jdbc:mysql://localhost:3306/broadleafcommerce_20
    ant.blCMSStorage.userName=root
    ant.blCMSStorage.password=
    ant.blCMSStorage.driverClassName=com.mysql.jdbc.Driver
    
  2. 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-create-sql and build-update-sql tasks in site/build.xml

  1. Delete the <target name="build-create-sql"> element and the <target name="build-update-sql"> element, as they are out-of-date

  2. Add the following to build.xml

    <target name="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.
        -->
        <mkdir dir="target/sql/create"/>
        <artifact:pom id="myPom" file="pom.xml" />
        <artifact:dependencies filesetId="pomDeps" pomRefId="myPom" useScope="compile" />
        <property name="baseTarget" location="target/${myPom.build.finalName}/WEB-INF"/>
        <fileset id="libDir" dir="${baseTarget}/lib"/>
        <path id="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>
                    <fileset refid="pomDeps" />
                    <intersect>
                        <fileset refid="pomDeps" />
                        <fileset refid="libDir" />
                    </intersect>
                </difference>
                <rsel:not>
                    <rsel:name name="**/*.pom" />
                </rsel:not>
            </restrict>
            <!--Add the lib directory to get all the dependencies required for the demo app-->
            <fileset refid="libDir"/>
            <dirset dir="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"/>-->
        <taskdef name="hibernatetool" classname="org.broadleafcommerce.common.util.sql.HibernateToolTask" classpathref="build.runtime.classpath"/>
        <hibernatetool destDir="target/sql/create" combinePersistenceUnits="false" refineFileNames="true">
            <!--add in additional persistence configuration related to the cms -->
            <classPathApplicationContext path="bl-cms-contentClient-applicationContext.xml"/>
            <classPathApplicationContext path="bl-open-admin-contentClient-applicationContext.xml"/>
            <!--add in additional persistence configuration for our core -->
            <classPathApplicationContext path="applicationContext.xml"/>
            <!--see description for my.app.context above -->
            <fileSystemApplicationContext path="src/main/webapp/WEB-INF/applicationContext.xml"/>
            <classPathApplicationContext path="bl-fake-applicationContext-ant.xml"/>
            <!--select the dialects and persistence units to export-->
            <jpaconfiguration persistenceUnit="blPU" dialect="${ant.hibernate.sql.ddl.dialect}" />
            <jpaconfiguration persistenceUnit="blSecurePU" dialect="${ant.hibernate.sql.ddl.dialect}" />
            <jpaconfiguration persistenceUnit="blCMSStorage" dialect="${ant.hibernate.sql.ddl.dialect}" />
            <!--other required elements-->
            <classpath refid="build.runtime.classpath" />
            <hbm2ddl export="false" update="false" create="true"/>
        </hibernatetool>
    </target>

    <target name="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.
        -->
        <mkdir dir="target/sql/update"/>
        <artifact:pom id="myPom" file="pom.xml" />
        <artifact:dependencies filesetId="pomDeps" pomRefId="myPom" useScope="compile" />
        <property name="baseTarget" location="target/${myPom.build.finalName}/WEB-INF"/>
        <fileset id="libDir" dir="${baseTarget}/lib"/>
        <path id="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>
                    <fileset refid="pomDeps" />
                    <intersect>
                        <fileset refid="pomDeps" />
                        <fileset refid="libDir" />
                    </intersect>
                </difference>
                <rsel:not>
                    <rsel:name name="**/*.pom" />
                </rsel:not>
            </restrict>
            <!--Add the lib directory to get all the dependencies required for the demo app-->
            <fileset refid="libDir"/>
            <dirset dir="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"/>-->
        <taskdef name="hibernatetool" classname="org.broadleafcommerce.common.util.sql.HibernateToolTask" classpathref="build.runtime.classpath" />
        <hibernatetool destDir="target/sql/update" combinePersistenceUnits="false" refineFileNames="true">
            <!--add in additional persistence configuration related to the cms -->
            <classPathApplicationContext path="bl-cms-contentClient-applicationContext.xml"/>
            <classPathApplicationContext path="bl-open-admin-contentClient-applicationContext.xml"/>
            <!--add in additional persistence configuration for our core -->
            <classPathApplicationContext path="applicationContext.xml"/>
            <!--see description for my.app.context above -->
            <fileSystemApplicationContext path="src/main/webapp/WEB-INF/applicationContext.xml"/>
            <classPathApplicationContext path="bl-fake-applicationContext-ant.xml"/>
            <!--select the dialects and persistence units to export-->
            <jpaconfiguration persistenceUnit="blPU" dialect="${ant.hibernate.sql.ddl.dialect}" 
                url="${ant.blPU.url}" 
                userName="${ant.blPU.userName}" 
                password="${ant.blPU.password}" 
                driverClassName="${ant.blPU.driverClassName}"/>
            <jpaconfiguration persistenceUnit="blSecurePU" dialect="${ant.hibernate.sql.ddl.dialect}" 
                url="${ant.blSecurePU.url}" 
                userName="${ant.blSecurePU.userName}" 
                password="${ant.blSecurePU.password}" 
                driverClassName="${ant.blSecurePU.driverClassName}"/>
            <jpaconfiguration persistenceUnit="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-->
            <classpath refid="build.runtime.classpath" />
            <hbm2ddl export="false" update="true" create="false"/>
        </hibernatetool>
    </target>
    ```

-------------

**Item**: Update your current 2.2 database schema to be 3.0 compliant

1. 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
    - Open the emitted update sql file: site/target/sql/update/\*Dialect\_blPU.sql
    - Execute the contents of this sql file against your target schema using your favorite sql execution environment

-------------

**Item**: Update admin permissions

1. 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           |

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

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

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

5. Download the re-population sql: <https://github.com/BroadleafCommerce/BroadleafCommerce/blob/broadleaf-3.0.0-GA/core/broadleaf-framework/src/main/resources/config/bc/sql/load_admin_permissions.sql>

6. Execute the re-population sql against your database using your favorite sql execution environment

7. Rebuild your `BLC_ADMIN_ROLE_PERMISSION_XREF` table mapping your custom roles to the appropriate permissions
    - If you have **NOT** altered any roles and took advantage of the roles from the 2.2 demo starter project, you can execute the following in your favorite sql execution environment to rebuild the `BLC_ADMIN_ROLE_PERMISSION_XREF` table.

    ```sql
    -- Super User
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-1);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-6);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-11);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-16);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-21);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-26);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-31);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-36);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-41);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-46);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-51);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-56);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-61);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-62);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-63);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-68);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-73);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-78);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-83);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-88);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (1,-93);

    -- Merchandiser
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (2,-1);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (2,-6);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (2,-11);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (2,-16);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (2,-21);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (2,-56);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (2,-83);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (2,-88);

    -- Promotions
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (3,-1);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (3,-26);

    -- CSR
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (4,-1);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (4,-31);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (4,-36);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (4,-41);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (4,-46);

    -- CMS Editor
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (5,-1);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (5,-51);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (5,-56);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (5,-61);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (5,-62);

    -- CMS Approver
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (6,-1);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (6,-51);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (6,-56);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (6,-61);
    INSERT INTO BLC_ADMIN_ROLE_PERMISSION_XREF (ADMIN_ROLE_ID, ADMIN_PERMISSION_ID) VALUES (6,-63);
    ```

-------------

**Item**: Add data for admin sections and modules

1. Download the population sql: <https://github.com/BroadleafCommerce/BroadleafCommerce/blob/broadleaf-3.0.0-GA/core/broadleaf-framework/src/main/resources/config/bc/sql/load_admin_menu.sql>

2. Delete your current `BLC_ADMIN_MODULE` and `BLC_ADMIN_SECTION` tables

3. Execute the population sql against your database using your favorite sql execution environment

-------------

**Item**: Address Hibernate 4 change for boolean fields from Bit to TinyInt (applies to MySql)

1. 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.

2. 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)

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

-------------

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

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

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

3. 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

1. 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**: Additional admin updates

1. Remove the `templates` directory from `admin/src/main/webapp/WEB-INF`

-------------

**Item**: Property file updates

1. Remove the `use.jrebel.compatibility.mode` property as it is no longer used.
2. Add `thymeleaf.view.resolver.cache=true` to common-shared.properties and `thymeleaf.view.resolver.cache=false` to development-shared.properties

## Considerations

**Admin Customization Considerations (If your current implementation has admin customizations)**

1. GWT has been phased out and is no longer supported for admin UI/functionality customization.
2. Logical portions of the admin are broken up into Modules, which themselves contains sections.
3. Modules are represented in the `BLC_ADMIN_MODULE` table and sections are represented in the `BLC_ADMIN_SECTION` table.
4. @AdminPresentation annotations in the Broadleaf domain classes support most of the functionality observed in the admin.
5. 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.
6. 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](https://github.com/BroadleafCommerce/BroadleafCommerce/blob/broadleaf-3.0.0-GA/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/catalog/domain/ProductImpl.java) for a variety of concrete usage examples.
7. 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**

1. 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.
2. 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).
3. In version 3.0, we have done away with the Order Item splitting concept in favor of OrderItemPriceDetails.
4. 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.
5. As a result, a call to OrderItem.getPrice() now returns an average of the price details for an item.
6. 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**

1. The MVEL generated for offers in version 2.2 may be incompatible with the new 3.0 rule builder UI.
2. Incompatible rules will still function in the system, but will be displayed in the admin page as immutable,raw MVEL.
3. 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.

**Translation Considerations (if your site requires multiple language support)**

1. Broadleaf 3.0 offers new field-level translation in the admin (denoted by a globe icon - see product name for an example).
2. To take advantage of this new translation service, consider moving your catalog translations to the `BLC_TRANSLATION` table.
3. Take a look at the 3.0 demo site `BLC_TRANSLATION` data for examples. ([Sample translation data](https://github.com/BroadleafCommerce/DemoSite/blob/broadleaf-3.0.0-GA/core/src/main/resources/sql/load_catalog_i18n_data_ES.sql))

**Heat Clinic Considerations**

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.2 and 3.0, you can utilize [this GitHub branch compare link](https://github.com/BroadleafCommerce/DemoSite/compare/BroadleafCommerce-2.2.x...admin3).