Extending Entities
Sometimes, the entities provided by Broadleaf Commerce will not be enough to fulfill your needs. For example, for specific business reasons, you may be required to represent an order id in a specific way that is incompatible with the internal order id representation used by Broadleaf Commerce. In this case, it would be desirable to add an additional field to the order that can hold a custom order id that you have generated to fulfill your requirement. To achieve this end, we must employ entity extensions.
Let's start by showing an implementation example of our custom entity MyOrderImpl
.
@Entity
@Table(name = "MY_ORDER")
public class MyOrderImpl extends OrderImpl {
private static final long serialVersionUID = 1L;
@Column(name = "MY_ORDER_ID")
private String myOrderId;
... getters / setters / equals / hashcode ...
}
Here, we've created a new custom entity that extends OrderImpl
from Broadleaf Commerce. We've added our custom order id field, myOrderId
, and, using JPA annotation, we have tied this entity and it's fields to a table and columns in the database.
Note: All entity extensions in Broadleaf Commerce use standard JPA strategies.
If you know how to use JPA, then you know how to work with and extend Broadleaf Commerce entities. Of course, you will need a table called MY_ORDER
in the non-secure schema (see Database Model) to back this entity. It should have an ORDER_ID
field capable of holding long integers (this field joins your new table with the Broadleaf Commerce order table) and a MY_ORDER_ID
field of the type VarChar
to hold your custom order id.
Now that we've created our entity extension, we need to notify Broadleaf Commerce of its existence and how to instantiate it. To do this, you will need to add a bean configuration to your application context:
<bean id="org.broadleafcommerce.core.order.domain.Order" class="com.mycompany.order.domain.MyOrderImpl" scope="prototype"/>
Finally, we need to add the new entity class to the persistence unit configuration in your persistence.xml
. This could end up looking similar to the following:
<persistence-unit name="blPU" transaction-type="RESOURCE_LOCAL">
...
<class>com.mycompany.order.domain.MyOrderImpl</class>
...
</persistence-unit>
Please refer to the Persistence Configuration section for more information on setting your Broadleaf Commerce application up for persistence.
This is the least amount of configuration required for Broadleaf Commerce to utilize your entity. Once configured, Broadleaf Commerce will now create an instance of MyOrderImpl
whenever a new Order
instance is required.
The only problem with this simplistic approach is that, in this case, the entity is instantiated only and the new myOrderId
field is not set. This may be fine for many custom field types, but in our case, it's desirable for the myOrderId
field to be set immediately. Let's examine some approaches to remedy this situation.
- Extend the
OrderDaoImpl
create()
method and add code to set your custom order id. (This is a similar approach to service extension - see the Service Extension Guide for more information.) - Add a factory bean for the
myOrderId
field to yourOrderImpl
extension configuration in Spring.
When applicable, we recommend using the factory bean approach, as it provides you with an opportunity to achieve a looser coupling with Broadleaf Commerce. Let's review how this might look. We'll start with the Factory Bean:
public class MyOrderIdFactoryBean implements FactoryBean {
public Object getObject() throws Exception {
String myOrderId = null;
//TODO add some code to create the custom order id
return myOrderId;
}
public Class getObjectType() {
return String.class;
}
public boolean isSingleton() {
return false;
}
}
This simple factory bean merely provides Spring with an Object instance and tells Spring the Class type of the object. In our case, we're creating a custom order id of the type String.
Now, let's add configuration to include our new id generation factory.
<bean id="org.broadleafcommerce.core.order.domain.Order" class="com.mycompany.order.domain.MyOrderImpl" scope="prototype">
<property name="myOrderId">
<bean class="com.mycompany.order.service.MyOrderIdFactoryBean"/>
</property>
</bean>
We've replaced the simple bean definition from above with a slightly more complex version that includes our factory bean. Now, when Broadleaf Commerce uses Spring to acquire an Order
instance, an instance of MyOrderImpl
will be returned with the myOrderId
field set with the value returned from MyOrderIdFactoryBean
.