@Stateful
@Name("TicketingSystem")
public class TicketBean implements TicketBeanItf {
@PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager em;
@In(create = true)
@Out
private Ticket ticket;
// We make this available to the business process
@Out(scope=ScopeType.BUSINESS_PROCESS, required=false)
long ticketId;
@CreateProcess(definition="TroubleTicketing")
public void createTicket() {
em.persist(ticket);
// Keep a reference to the ticketId in your biz process
ticketId = ticket.getTicketId();
}
}
@Stateful
@Name("TicketingSystem")
public class TicketBean implements TicketBeanItf {
@PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager em;
@In(create = true)
@Out
private Ticket ticket;
// We make this available to the business process
@Out(scope=ScopeType.BUSINESS_PROCESS, required=false)
long ticketId;
@CreateProcess(definition="TroubleTicketing")
public void createTicket() {
em.persist(ticket);
// Keep a reference to the ticketId in your biz process
ticketId = ticket.getTicketId();
}
} < type="application/x-shockwave-flash" width="14" height="15" src="http://snowfox2008.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" src="http://snowfox2008.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%40Stateful%20%20%0A%40Name(%22TicketingSystem%22)%20%20%0A%20%20%20%0Apublic%20class%20TicketBean%20implements%20TicketBeanItf%20%7B%20%20%0A%20%20%20%0A%40PersistenceContext(type%3DPersistenceContextType.EXTENDED)%20%20%0AEntityManager%20em%3B%20%20%0A%20%20%20%0A%40In(create%20%3D%20true)%20%20%0A%40Out%20%20%0Aprivate%20Ticket%20ticket%3B%20%20%0A%20%20%20%0A%2F%2F%20We%20make%20this%20available%20to%20the%20business%20process%20%20%0A%40Out(scope%3DScopeType.BUSINESS_PROCESS%2C%20required%3Dfalse)%20%20%0Along%20ticketId%3B%20%20%0A%20%20%20%0A%40CreateProcess(definition%3D%22TroubleTicketing%22)%20%20%0A%20public%20void%20createTicket()%20%7B%20%20%0A%20%20%20%20em.persist(ticket)%3B%20%20%0A%20%20%20%20%2F%2F%20Keep%20a%20reference%20to%20the%20ticketId%20in%20your%20biz%20process%20%20%0A%20%20%20%20ticketId%20%3D%20ticket.getTicketId()%3B%20%20%0A%20%7D%20%20%0A%20%20%20%20%0A%7D%20%20%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15">
@Stateful
@Name("TicketingSystem")
public class TicketBean implements TicketBeanItf {
@PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager em;
@In(create = true)
@Out
private Ticket ticket;
// We make this available to the business process
@Out(scope=ScopeType.BUSINESS_PROCESS, required=false)
long ticketId;
@CreateProcess(definition="TroubleTicketing")
public void createTicket() {
em.persist(ticket);
// Keep a reference to the ticketId in your biz process
ticketId = ticket.getTicketId();
}
}
JBPM有一个内建的异常处理器,能够被应用在单一节点或者整个流程。
<exception-handler exception-class = "java.lang.Exception">
<action class = "com.sample.handlers.BPMExceptionHandler">
</action>
</exception-handler>
<exception-handler exception-class = "java.lang.Exception">
<action class = "com.sample.handlers.BPMExceptionHandler">
</action>
</exception-handler>
<exception-handler exception-class="java.lang.Exception">
<action class="com.sample.handlers.BPMExceptionHandler"></action>
</exception-handler> 你或许曾经被诱惑在JBPM中使用异常处理机制来决策执行流,不要这样做!JBPM的机制并不完全与java的异常处理相似,在java中,一个捕获的异常能够对控制流产生影响。而在jBPM的案例中,控制流不能被jBPM的异常处理机制改变。异常可以被捕获或不捕获。不捕获的异常被扔给客户端(例如,调用 token.signal()方法的客户端)或者这个异常被jBPM异常处理器捕获。对于捕获的异常,graph execution 会当作没有异常发生继续执行。
依赖于被扔出的异常,在你的Action中捕获业务异常并且设置一些流程变量也是一个好的设计。然后你可以在流程中构造一个决策节点,用来选择一个特定的执行路径。
jBPM是一个状态机:流程描述和运行时的状态被持久化到数据库中,但是在一个集群环境中,他们不会自动失败转发。如果一个集群节点失败了,这时正在执行的一些触发器(UI,JMS,重复执行的计时器)需要停止执行并且不得不重新启动。依赖于你所处的事务上下文,这些动作能够被自动执行(重新传递JMS消息,重新执行计时器)或者请求UI交互(如果集群节点宕机需要重启时,显示错误消息给用户)。
那么,在你的工作流中增加这些特性的最简单的方式是什么?对于大多数的案例,最佳的解决方案是在你的应用中用一个无状态的会话bean来封装jBPM API的调用,并且在最后构建集群。
一个Superstate是一组节点:它是一种将节点组合成相关集合的方便的方式,是在流程中实例阶段的表示。例如,一个应用程序能够分阶段组合流程中的所有节点。动作(Action)可以被关联到superstate事件上。一个重要的意义就是一个令牌(token)能够在给定的时间上被多层嵌套。这可以方便地来检查一个流程是否被执行了,例如在开始阶段。
有时候开发人员(我也是)不去寻找更简单的解决方案,或许用jBPM内建的节点来建模流程而导致一个不必要的复杂流程。
private String taskLocation;
public String getTaskLocation() {
return taskLocation;
}
public void setTaskLocation(String taskLocation){
this.taskLocation = taskLocation;
}
private String taskLocation;
public String getTaskLocation() {
return taskLocation;
}
public void setTaskLocation(String taskLocation){
this.taskLocation = taskLocation;
}
public String getTaskLocation() {
return taskLocation;
}
public void setTaskLocation(String taskLocation){
this.taskLocation = taskLocation;
}
<property name="taskLocation" column= "TASKLOCATION_"></property>
<property name="taskLocation" column= "TASKLOCATION_"></property>
String taskLocation = taskElement.attributeValue("taskLocation");
if (taskLocation==null) {
taskLocation = taskElement.attributeValue("taskLocation");
}
if (taskLocation != null){
task.setLocation(taskLocation);
}
String taskLocation = taskElement.attributeValue("taskLocation");
if (taskLocation==null) {
taskLocation = taskElement.attributeValue("taskLocation");
}
if (taskLocation != null){
task.setLocation(taskLocation);
}
String taskLocation = taskElement.attributeValue("taskLocation");
taskLocation = taskElement.attributeValue("taskLocation");
}
if (taskLocation != null){
task.setLocation(taskLocation);
}
<filter name= "filterPriority" condition= ":paramPriority = PRIORITY_" />
<filter name="filterDesc" condition= ":paramDesc = DESCRIPTION_" />
<filter name="filterId" condition= "str(ID_) LIKE (:paramId) " />
<filter name="filterCreate" condition= "CREATE_ BETWEEN :paramFrom and :paramTo" />
<filter name= "filterPriority" condition= ":paramPriority = PRIORITY_" />
<filter name="filterDesc" condition= ":paramDesc = DESCRIPTION_" />
<filter name="filterId" condition= "str(ID_) LIKE (:paramId) " />
<filter name="filterCreate" condition= "CREATE_ BETWEEN :paramFrom and :paramTo" />
String sql = "from org.jbpm.taskmgmt.exe.TaskInstance";
session.enableFilter("filterPriority").setParameter("paramPriority","2");
Query queryParent = session.createQuery(sql);
List list = queryParent.list();
Iterator iter = list.iterator();
while (iter.hasNext()) {
TaskInstance taskInstance = (TaskInstance)iter.next();
}
String sql = "from org.jbpm.taskmgmt.exe.TaskInstance";
session.enableFilter("filterPriority").setParameter("paramPriority","2");
Query queryParent = session.createQuery(sql);
List list = queryParent.list();
Iterator iter = list.iterator();
while (iter.hasNext()) {
TaskInstance taskInstance = (TaskInstance)iter.next();
}
<filter name="filterPriority" condition=":paramPriority = PRIORITY_"/>
<filter name="filterDesc" condition=":paramDesc = DESCRIPTION_"/>
<filter name="filterId" condition="str(ID_) LIKE (:paramId) "/>
<filter name="filterCreate" condition="CREATE_ BETWEEN :paramFrom and :paramTo"/>
String sql = "from org.jbpm.taskmgmt.exe.TaskInstance";
session.enableFilter("filterPriority").setParameter("paramPriority","2");
Query queryParent = session.createQuery(sql);
List list = queryParent.list();
Iterator iter = list.iterator();
while (iter.hasNext()) {
TaskInstance taskInstance = (TaskInstance)iter.next();
}
如果你有复杂的规则,雇用一个Drools开发人员
首先要理解:
BPEL是一个XML语言,用来描述长期运行的web服务的交互。它主要被用来集中地编排消息交换,因此在SOA中是一个关键的要素。
同外部代理交互
对于活动的调度
异常处理
错误恢复
即使它们有一些共同点,但这些元素的具体表达式导致不同的受众,讨论它们对于过程的描述:
BPEL用复杂的场景来描述结构化的组成
而与外部代理的交互也被不同地实现:
JPDL是面向对象的,因此它可以作为公司应用组件的主干
BPEL将人之间的交互代理给 Partner Service 实现
jPDL提供集成的任务管理
那么我应该什么时候使用BPEL?
当没有直接的人员涉及(即无人工干预的流程),同时你更需要对长时间运行的业务流程很好支持的情况下。
当你需要以一个相对简单的方式取得事务补偿时。在已经完全成功的业务流程中的补偿,或者取消步骤是业务流程中最重要的概念。补偿的目标是撤销,即消除一个业务流程中已被放弃的一部分已经被执行的节点所造成的影响。
当这些条件不满足时使用JPDL。
有时候开发人员(我也是)不去寻找更简单的解决方案,或许用jBPM内建的节点来建模流程而导致一个不必要的复杂流程。
private String taskLocation;
public String getTaskLocation() {
return taskLocation;
}
public void setTaskLocation(String taskLocation){
this.taskLocation = taskLocation;
}
private String taskLocation;
public String getTaskLocation() {
return taskLocation;
}
public void setTaskLocation(String taskLocation){
this.taskLocation = taskLocation;
}
public String getTaskLocation() {
return taskLocation;
}
public void setTaskLocation(String taskLocation){
this.taskLocation = taskLocation;
}
<property name="taskLocation" column= "TASKLOCATION_"></property>
<property name="taskLocation" column= "TASKLOCATION_"></property>
String taskLocation = taskElement.attributeValue("taskLocation");
if (taskLocation==null) {
taskLocation = taskElement.attributeValue("taskLocation");
}
if (taskLocation != null){
task.setLocation(taskLocation);
}
String taskLocation = taskElement.attributeValue("taskLocation");
if (taskLocation==null) {
taskLocation = taskElement.attributeValue("taskLocation");
}
if (taskLocation != null){
task.setLocation(taskLocation);
}
String taskLocation = taskElement.attributeValue("taskLocation");
taskLocation = taskElement.attributeValue("taskLocation");
}
if (taskLocation != null){
task.setLocation(taskLocation);
}
<filter name= "filterPriority" condition= ":paramPriority = PRIORITY_" />
<filter name="filterDesc" condition= ":paramDesc = DESCRIPTION_" />
<filter name="filterId" condition= "str(ID_) LIKE (:paramId) " />
<filter name="filterCreate" condition= "CREATE_ BETWEEN :paramFrom and :paramTo" />
<filter name= "filterPriority" condition= ":paramPriority = PRIORITY_" />
<filter name="filterDesc" condition= ":paramDesc = DESCRIPTION_" />
<filter name="filterId" condition= "str(ID_) LIKE (:paramId) " />
<filter name="filterCreate" condition= "CREATE_ BETWEEN :paramFrom and :paramTo" />
String sql = "from org.jbpm.taskmgmt.exe.TaskInstance";
session.enableFilter("filterPriority").setParameter("paramPriority","2");
Query queryParent = session.createQuery(sql);
List list = queryParent.list();
Iterator iter = list.iterator();
while (iter.hasNext()) {
TaskInstance taskInstance = (TaskInstance)iter.next();
}
String sql = "from org.jbpm.taskmgmt.exe.TaskInstance";
session.enableFilter("filterPriority").setParameter("paramPriority","2");
Query queryParent = session.createQuery(sql);
List list = queryParent.list();
Iterator iter = list.iterator();
while (iter.hasNext()) {
TaskInstance taskInstance = (TaskInstance)iter.next();
}
<filter name="filterPriority" condition=":paramPriority = PRIORITY_"/>
<filter name="filterDesc" condition=":paramDesc = DESCRIPTION_"/>
<filter name="filterId" condition="str(ID_) LIKE (:paramId) "/>
<filter name="filterCreate" condition="CREATE_ BETWEEN :paramFrom and :paramTo"/>
String sql = "from org.jbpm.taskmgmt.exe.TaskInstance";
session.enableFilter("filterPriority").setParameter("paramPriority","2");
Query queryParent = session.createQuery(sql);
List list = queryParent.list();
Iterator iter = list.iterator();
while (iter.hasNext()) {
TaskInstance taskInstance = (TaskInstance)iter.next();
}
如果你有复杂的规则,雇用一个Drools开发人员
首先要理解:
BPEL是一个XML语言,用来描述长期运行的web服务的交互。它主要被用来集中地编排消息交换,因此在SOA中是一个关键的要素。
同外部代理交互
对于活动的调度
异常处理
错误恢复
即使它们有一些共同点,但这些元素的具体表达式导致不同的受众,讨论它们对于过程的描述:
BPEL用复杂的场景来描述结构化的组成
而与外部代理的交互也被不同地实现:
JPDL是面向对象的,因此它可以作为公司应用组件的主干
BPEL将人之间的交互代理给 Partner Service 实现
jPDL提供集成的任务管理
那么我应该什么时候使用BPEL?
当没有直接的人员涉及(即无人工干预的流程),同时你更需要对长时间运行的业务流程很好支持的情况下。
当你需要以一个相对简单的方式取得事务补偿时。在已经完全成功的业务流程中的补偿,或者取消步骤是业务流程中最重要的概念。补偿的目标是撤销,即消除一个业务流程中已被放弃的一部分已经被执行的节点所造成的影响。
当这些条件不满足时使用JPDL。