cancel
Showing results for 
Search instead for 
Did you mean: 

Serializing process variables

mariusz_cwikla
Champ in-the-making
Champ in-the-making
Hi,
I have a couple of questions regarding process variables storage, but the short one is: is there a way to create custom serializer for my process variables?

Let me provide some background:
- let's say that I use process variables as complex object, for example:

class Person implements Serializable{
  private String id, firstName, lastName;
  //setters & getters
}

1. I know, that when I use such object then Activiti serializes it using Java Seralization mechanism[/li]
2. let's say that in some point in time a developer upgrades such object:
2.1 he may add new attribute to object
2.2 he may remove attribute
2.3 he may rename an attribute (since he make a typo a week ago)
3. application is already deployed in production
4. I know that process variables for such complex objects are stored as byte array in ACT_GE_BYTEARRAY  table. Is there a way to upgrade my objects in that table by some SQL scripts?

1. One idea would be to create a proxy object and store only an "id" attribute. Then create readObject/writeObject methods that serialize/deserialize only id attribute. Rest of the attributes would be delegated, for example:


class PersonDelegate{
   private Person realPerson;
   private String id;
   
   private void writeObject(java.io.ObjectOutputStream out) throws IOException{      
      out.writeBytes(id);
   }
   private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{
      id = in.readLine();      
   }
   
   public String getFirstName(){
      loadPerson();
      return realPerson.getFirstName();
   }
   
   private void loadPerson(){
      if(realPerson==null)
         realPerson=use_my_service_to_load_person(id);
   }
}

Then I store only id in Activiti tables and real objects are stored somewhere else where I can manage my structure modification.

2. In user guide I found following sentence: "Activiti supports complex Java objects to be stored as process variables like Serializable objects, JPA entities or whole XML documents as Strings."

How can I store complex process variables as XML documents?

3. Another option is to use JPA support mentioned in 2), but I also want to use OSGi. I've seen, that Activiti supports OSGi, but I only found following configuration from book "Activiti in Action"

  <bean id="configurationFactory" class="org.activiti.osgi.blueprint.ConfigurationFactory">
    <property name="dataSource" ref="dataSource" />
    <property name="databaseSchemaUpdate" value="true" />
  </bean>
It does only contain configuration for dataSrouce, it does not contain configuration for JPA. It shouldn't be hard to add JPA to this configuration, but if anyone has already full configuration, I would be greatful I someone posts such configuration with JPA.
 
  So anyway, if I use JPA will I have my objects stored only in my tables instead of ACT_GE_BYTEARRAY as byte array?
 
Summary:
1. Is there a way to create custom serializer for my process variables?
2. How can I store complex process variables as XML documents?
3. If I use JPA will I have my process stored only in my tables instead of ACT_GE_BYTEARRAY as byte array?
4. Any other idea?
5. Can somebody provide me sample Blueprint configuration with JPA (regarding org.activiti.osgi.blueprint.ConfigurationFactory or some other classes).



Thanks in advance for any help.
4 REPLIES 4

jbarrez
Star Contributor
Star Contributor
wow, that's a lot of text 😉

1. Is there a way to create custom serializer for my process variables?

Yes, check the VariableTypes and the VariableType classes.
That's the way all variable serialization is implemented.

2. How can I store complex process variables as XML documents?

Then you'd need a custom serializer, indeed.

3. If I use JPA will I have my process stored only in my tables instead of ACT_GE_BYTEARRAY as byte array?

It will only store the primary key to your entity, nothing else.

4. Any other idea?

Nope 🙂

5. Can somebody provide me sample Blueprint configuration with JPA (regarding org.activiti.osgi.blueprint.ConfigurationFactory or some other classes).


Sorry, I'm no osgi user…

mariusz_cwikla
Champ in-the-making
Champ in-the-making
Hello,
thanks for your answer. I'll check VariableTypes and VariableType classes.

I also did a small research, and a quick test shows that ConfigurationFactory from activiti-osgi.jar does not work properly with JPA, but I found a workaround.
1. In a book "Activiti in Action" there is following example:

  <bean id="configurationFactory" class="org.activiti.osgi.blueprint.ConfigurationFactory">
    <property name="dataSource" ref="dataSource" />
    <property name="databaseSchemaUpdate" value="true" />
  </bean>

  <bean id="configuration" factory-ref="configurationFactory" factory-method="getConfiguration" />
ConfigurationFactory instantiates StandaloneProcessEngineConfiguration object.
I tried to add jpaPersistenceUnitName/jpaHandleTransaction/jpaCloseEntityManager properties, but only first one works (I didn't test it thorougly, I just can say that following Blueprint bean gets deployed):

<bean id="configurationFactory" class="com.asseco.ufe.prototyping.workflow.activiti.ConfigurationFactory">
  <property name="dataSource" ref="activitiDS" />
  <property name="databaseSchemaUpdate" value="true" />

</bean>

<bean id="configuration" factory-ref="configurationFactory" factory-method="getConfiguration">
   <property name="jpaPersistenceUnitName" value="prototypeJPA" />
</bean>
When I added jpaHandleTransaction/jpaCloseEntityManager properties to configuration bean:

<bean id="configuration" factory-ref="configurationFactory" factory-method="getConfiguration">
   <property name="jpaPersistenceUnitName" value="prototypeJPA" />
   <property name="jpaHandleTransaction" value="true"/>
     <property name="jpaCloseEntityManager" value="true"/>
</bean>

then I got following error:

Caused by: org.osgi.service.blueprint.container.ComponentDefinitionException: No setter for jpaHandleTransaction property
at org.apache.aries.blueprint.container.BeanRecipe.setProperty(BeanRecipe.java:940)
at org.apache.aries.blueprint.container.BeanRecipe.setProperties(BeanRecipe.java:903)

It's strange, since there is setJpaHandleTransaction method in base class. It might be a bug in Apache Aries (I use 1.0), but on the other hand it might be caused by StandaloneProcessEngineConfiguration hierarchy. "setJpaHandleTransaction" method is both in ProcessEngineConfigurationImpl and ProcessEngineConfiguration. Here is the hierarchy:

ProcessEngineConfiguration <- contains setJpaHandleTransaction
          ^
          |
ProcessEngineConfigurationImpl <- contains setJpaHandleTransaction
          ^
          |
StandaloneProcessEngineConfiguration <- does not contain setJpaHandleTransaction

2 .So, anyway, my workaround for this problem is to create custom factory based on ConfigurationFactory from activiti-osgi like this:

<bean id="configurationFactory" class="com.mc.activiti.MyConfigurationFactory">
  <property name="dataSource" ref="activitiDS" />
  <property name="databaseSchemaUpdate" value="true"/> 
  <property name="jpaHandleTransaction" value="true"/>
    <property name="jpaCloseEntityManager" value="true"/>
    <property name="jpaEntityManagerFactory" ref="myEntityManagerFactory"/>
</bean>

<bean id="configuration" factory-ref="configurationFactory" factory-method="getConfiguration">
</bean>

<reference id="myEntityManagerFactory"
  interface="javax.persistence.EntityManagerFactory" filter="osgi.unit.name=myJPA"/>
and here's factory code

public class SecondConfigurationFactory {

    private DataSource dataSource;
    private String databaseSchemaUpdate;
    private boolean jobExecutorActivate = true;
private boolean jpaHandleTransaction;
private boolean jpaCloseEntityManager;

    private EntityManagerFactory jpaEntityManagerFactory;
    public StandaloneProcessEngineConfiguration getConfiguration() {
    StandaloneProcessEngineConfiguration conf =
              new StandaloneProcessEngineConfiguration();
      conf.setDataSource(dataSource);
      conf.setDatabaseSchemaUpdate(databaseSchemaUpdate);
      conf.setJobExecutorActivate(jobExecutorActivate);     
      conf.setJpaEntityManagerFactory(jpaEntityManagerFactory);
      conf.setJpaHandleTransaction(jpaHandleTransaction);
      conf.setJpaCloseEntityManager(jpaCloseEntityManager);
      return conf;
    }  
//setters for all attributes
}

Currently it works for me, but is this correct in long-term? And if it is, can I ask a request to add JPA support for Blueprint?

trademak
Star Contributor
Star Contributor
Hi,

Can you add a JIRA issue for this and add sample code to show this error?

Best regards,

mariusz_cwikla
Champ in-the-making
Champ in-the-making
Sure,
I have just opened an issue http://jira.codehaus.org/browse/ACT-1503