6.0 Migration
These migration notes assumes that you are going from 5.2 demo to the 6.0 demo. There might be additional migration steps necessary for your particular implementation of Broadleaf. If so, please let us know through our Gitter, our Google Group, or by submitting a pull request to this documentation repo at https://github.com/BroadleafCommerce/docs.
Overview of new features in the 6.0.0-GA release are detailed within [[6.0.0-GA Release Notes | 6.0.0 GA]].
Module Compatibility with 6.0
If you are using any other Broadleaf modules, then those module versions will need to be updated to be compatible with broadleaf framework 6.0. Here is a compatibility chart listing all of the module versions that are compatible with broadleaf 6.0.
Module Name | Version | Migration Notes |
---|---|---|
broadleaf-menu | 3.0.0-GA | - |
broadleaf-multitenant-singleschema | 4.0.0-GA | - |
broadleaf-theme | 3.0.0-GA | - |
broadleaf-pricelist | 4.0.0-GA | - |
broadleaf-custom-field | 3.0.0-GA | - |
broadleaf-advanced-cms | 3.0.0-GA | - |
broadleaf-advanced-offer | 3.0.0-GA | - |
broadleaf-account-credit | 4.0.0-GA | - |
broadleaf-advanced-inventory | 3.0.0-GA | - |
broadleaf-common-modules-enterprise | 4.0.0-GA | - |
broadleaf-jobs-events | 3.0.0-GA | - |
broadleaf-i18n-enterprise | 3.0.0-GA | - |
broadleaf-enterprise | 4.0.0-GA | - |
broadleaf-account | 3.0.0-GA | - |
broadleaf-enterprise-search | 3.0.0-GA | - |
broadleaf-customer-segment | 2.0.0-GA | - |
broadleaf-merchandising-group | 2.0.0-GA | - |
broadleaf-api | 3.0.0-GA | - |
broadleaf-oms | 3.0.0-GA | - |
broadleaf-cart-rules | 2.0.0-GA | - |
broadleaf-common-presentation | 1.1.0-GA | - |
broadleaf-thymeleaf-presentation | 2.0.0-GA | - |
broadleaf-product-type | 2.0.0-GA | - |
broadleaf-catalog-access-policy | 2.0.0-GA | - |
broadleaf-quote | 2.0.0-GA | - |
broadleaf-marketplace | 2.0.0-GA | - |
broadleaf-process | 2.0.0-GA | - |
broadleaf-export | 2.0.0-GA | - |
broadleaf-import | 3.2.0-GA | - |
broadleaf-affiliate | 2.0.0-GA | - |
broadleaf-contenttests | 3.0.0-GA | - |
broadleaf-subscription | 3.0.0-GA | - |
broadleaf-punchout2go | 2.0.0-GA | - |
broadleaf-free-geo-ip | 2.0.0-GA | - |
broadleaf-max-mind-geo | 2.0.0-GA | - |
Major feats
- Updated core 3rd-party dependency baselines
- Spring 5
- Spring Boot 2
- Spring Security 5
- Hibernate 5
- Upgraded base JDK from 7 to 8
- Thus, the minimum system requirement for Broadleaf 6.0 is no longer Java 7 but Java 8
- Upgraded Solr APIs to support Solr 7
- While the APIs have been tested to support a Solr 5 server, it is advised to migrate to Solr 7 and do a full reindex
- Added support for Java Servlet API 3.1.0
- Dropped support for MSSQL
Dependency Updates
- Removed
- commons-digest
- velocity
- No longer used
- commons-lang
- Replaced by commons-lang3
- YUICompressor for Javascript minification
- Usage replaced by Google Closure Compiler
- The
com.google.javascript:closure-compiler-unshaded
dependency can be removed from the pom.xml as it's now a transitive dependency from Broadleaf - Still used for CSS minification
- Thymeleaf 2 support
- Updated
- Java Servlet API to 3.1
- Spring 4.3.17 -> 5.0.7
- Spring Security 4.3.x -> 5.0.6
- Spring Boot 1.5.12 -> 2.0.3
- Hibernate 4.1.11 -> 5.2.17
- Hibernate validator to 6.0.9
- JPA to 2.1
- Jackson to 2.9
- commons-io 2.4 -> 2.6
- commons-codec 1.4 -> 1.11
- commons-dbcp 1.2.2 -> 2.2.0
- Required changing groupId and artifactId from commons-dbcp:commons-dbcp to org.apache.commons:commons-dbcp2
- commons-lang -> commons-lang3
- esapi 2.1.0 -> 2.1.0.1
- guava 12 -> 22
- quartz-scheduler 2.2 -> 2.3
com.broadleafcommerce:broadleaf-product-type
no longer needs a version declared as the Broadleaf BOM defines the correct version.org.thymeleaf.extras:thymeleaf-extras-springsecurity4:3.0.1-RELEASE
->org.thymeleaf.extras:thymeleaf-extras-springsecurity5
- The version for
thymeleaf-extras-springsecurity5
doesn't need to be defined as Spring Boot starter defines the version for you
- The version for
Solr 7 upgrade
Spring 5 changes
- Dropped support for Log4j 1.x
- Migrate to Log4j2 or Logback
- Log4jConfigListener removed with no replacement
- https://docs.spring.io/spring/docs/5.0.0.RC3/spring-framework-reference/overview.html#overview-logging
Hibernate 5 updates
Logging
In order to reduce the amount of logging to what's necessary add <logger name="org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl" level="ERROR"/>
to the logback logging file. There's some unnecessary logging that was changed to INFO
that is very loud.
Dialects
- MySQL (changed)
- Replace
org.hibernate.dialect.MySQL5InnoDBDialect
(now deprecated) - with
org.hibernate.dialect.MySQL5Dialect
and sethibernate.dialect.storage_engine=innodb
as an environment variable or JVM system property instead
- Replace
- Postgres (changed)
- Replace
org.hibernate.dialect.PostgreSQLDialect
(now deprecated) - with
org.broadleafcommerce.common.dialect.BroadleafPostgreSQLDialect
- Replace
- HSQL (unchanged)
org.hibernate.dialect.HSQLDialect
- Oracle (unchanged)
org.hibernate.dialect.Oracle10gDialect
- MSSQL (unchanged)
org.hibernate.dialect.SQLServerDialect
Naming Strategies
Hibernate 5 introduced a change to their naming strategy contract:
Historically, Hibernate provided just a singular contract for applying a "naming strategy". Starting in 5.0, this has been split into 2 distinct contracts: *
ImplicitNamingStrategy
- is used whenever a table or column is not explicitly named to determine the name to use. *PhysicalNamingStrategy
- is used to convert a "logical name" (either implicit or explicit) name of a table or column into a physical name (e.g. following corporate naming guidelines)
This affects Broadleaf insofar as the default ImplicitNamingStrategy
has been changed in order to be compliant with JPA 2.0 standards. Where before a column without an explicitly labelled name (e.g., @Column
instead of @Column(name = "COLUMN_NAME
) might be named TABLE_NAME_FIELD_NAME
, the new standard causes Hibernate to expect the name to be EntityName_FIELD_NAME
. All cases in Broadleaf of implicit naming have been made explicit to prevent any need for schema migration changes on Broadleaf's account. However, clients will need to consider any custom and extended entities that may be using the implicit naming strategy.
There are 2 options for handling this change:
- (Easy Way) In the short term to make the migration easy, the legacy implicit naming strategy can be reintroduced by setting the following property for each persistence unit as with other Hibernate properties:
<persistenceUnit>.hibernate.implicit_naming_strategy=legacy-jpa
<persistenceUnit>
could beblPU
,blCMSStorage
,blSecure
, or any other persistence unit present
- (Involved Way) Eventually, it is recommded to move away from using a legacy feature of a 3rd party dependency since it may be removed in the next upgrade. To do so, replace all cases where implicit naming is relied upon for tables and columns by providing explicit names. Some examples:
@Table
->@Table(name = "EXISITNG_TABLE_NAME"
@Column
->@Column(name = "EXISTING_COLUMN_NAME)
@JoinTable
->
@JoinTable(name = "EXISTING_TABLE_NAME",
joinColumns = @JoinColumn(name = "EXISTING_COLUMN_NAME", referencedColumnName = "REFERENCED_COLUMN_NMAE"),
inverseJoinColumns = @JoinColumn(name = "EXISTING_COLUMN_NAME", referencedColumnName = "REFERENCED_COLUMN_NAME"))
Additionally, the physical naming strategy can be overridden, but this is not necessary since Hibernate defaults to matching the physical and implicit (logical) names. Yet, to override set <persistenceUnit>.hibernate.physical_naming_strategy
to some.class.implementing.org.hibernate.boot.model.naming.PhysicalNamingStrategy
. The default class is org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Notes
Scheduled Jobs Updates
Quartz Scheduler 2.2 suffered from a bug that prevented cron expressions with increments (e.g., 0 0/60 * * * ?
) from being correctly validated. That was fixed in 2.3. However, that means that invalid increment values will now cause exceptions to be thrown when trying to run scheduled jobs. Please, correct any invalid cron expressions in BLC_SCHED_JOB.CRON_EXPRESSION
. Primarily, make sure that values for seconds and minutes are < 60 and hours are < 23. For example previously, the following would not throw an exception: 0 0/60 * * * ?
. However, it should now be changed to 0 0/59 * * * ?
. See allowed values for each field below:
Field | Allowed Values |
---|---|
Seconds | 0-59 |
Minutes | 0-59 |
Hours | 0-23 |
Day of month | 1-31 |
Month | 1-12 or Jan-Dec |
Day of week | 1-7 or SUN-SAT |
Year | empty or 1970-2099 |
Framework changes
General changes
- Removed:
- Support for Thymeleaf 2
- Remove the broadleaf-thymeleaf2-presentation dependency and replace it with broadlaef-thymeleaf3-presentation
- Thymeleaf upgrade blog post
-
RuntimeEnvironmentPropertiesConfigurer
- Instead, use
org.springframework.core.env.Environment
to access the current profile or@Profile
- Support for having a salt source for passwords
- No longer needed since Spring provides a salt for the encoders that need one
- Support for older password encoders
- BCrypt is our recommendation
- Sku browsing
- Previously Broadleaf somewhat supported sku browsing however the feature had not been updated over time and had stopped working as intended so it was simply removed.
- For most implementations this change does not affect them however any reference to the property
solr.index.use.sku
or any variations ofuse.sku
can be removed
- Support for Thymeleaf 2
- Added
- Out-of-box usage of commons-dbcp2 for creating data sources
- Various changes in API
- Change
#setMaxActive
to#setMaxTotal
- Out-of-box usage of commons-dbcp2 for creating data sources
Domain changes
MenuItem
no longer has a foreign key relationship withMedia
- The foreign key is replaced by a string field to hold the Media's URL
- Migration notes
ExternalId
field added toCustomer
- Previously, this was optionally woven on by the Import module
- To migrate, add a new string column,
EXTERNAL_ID
, toBLC_CUSTOMER
- This is an optional field and is used to map the customer record to an external system.
- If you are using the ProductType module version 1.1 or less, you will need to add a new column to the
BLC_PRODUCT_ADD_ON_XREF
table. The new column isADD_ON_SKU_ID
.
-- MySQL example
alter table BLC_PRODUCT_ADD_ON_XREF
add column `ADD_ON_SKU_ID` bigint(20) DEFAULT NULL;
- In one of the patch releases, we fixed the issue with Cart purge process failing due to duplicate
OrderAttributes
. This fix required adding a constraint on the tableblc_order_attribute
. Please add this if it has not been added yet.
-- Unique Constraint for PostgreSQL
ALTER TABLE blc_order_attribute ADD CONSTRAINT attr_name_order_id UNIQUE ("name",order_id);
-- Unique index for MySQL
ALTER TABLE blc_order_attribute add unique key `attr_name_order_id` (`name`,`order_id`);
Code Changes (Spring Boot)
The upgrade will require updates to configuration and application classes:
- ApplicationSolrConfiguration
- If configuring Solr clients using a configuration class, replace direct instantiations of solr client objects with builders:
new HttpSolrClient(url)
->new HttpSolrClient.Builder(primaryFulfillmentOrderSolrUrl).build()
- If configuring Solr clients using a configuration class, replace direct instantiations of solr client objects with builders:
- CorePersistenceConfig
- Change
org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder
->org.springframework.boot.jdbc.DataSourceBuilder
- Change
- Api/Admin/SiteApplication
- Change
org.springframework.boot.web.support.SpringBootServletInitializer
->org.springframework.boot.web.servlet.support.SpringBootServletInitializer
- Change uses of
org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
->org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
- Change
- Admin/SiteServletConfig
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
->org.springframework.web.servlet.config.annotation.WebMvcConfigurer
- Properties files where applicable
server.contextPath
->server.servlet.contextPath
New Broadleaf Hibernate Dialect for PostgreSQL
What
Introduced new custom Hibernate dialect to better support PostgreSQL.
Why
The PostgreSQL jdbc driver does not implement createClob()
, causing difficulty for Hibernate to correctly handle clobs for Postgres. Normally, a clob would be stored as a Postgres Large Object pointed to by an OID in the original column. However, because createClob()
is not implemented, the string value is placed directly into the column meant for the OID. Hibernate's Postgres dialect does not recognize that the column value is not an OID; therefore, an exception is thrown because Hibernate tries to cast the string to a long.
Thus, the custom BroadleafPostgreSQLDialect treats all Clob types as if they contain a string instead of an long (OID).
How to use
Set <persistenceUnit>.hibernate.dialect
to org.broadleafcommerce.common.dialect.BroadleafPostgreSQLDialect
where <persistenceUnit>
can be blPU
, blCMSStorage
, blSecure
, etc.
Notes on Logging for the PostgreSQL Clob
Once using the custom BroadleafPostgresSQLDialect, clobs should be handled as expected. However, you may still see INFO entries in the application logs related to the lack of support for createClob()
.
INFO o.h.e.j.e.i.LobCreatorBuilderImpl...
...
Caused by: java.sql.SQLFeatureNotSupportedException: Method org.postgresql.jdbc.PgConnection.createClob() is not yet implemented.
These are only INFO log entries and are harmless. The recommendation is to change the logging levels to WARN/ERROR.