Skip to content

Separating Domain Code and Implementation Code

Jinyoung Jang edited this page Oct 27, 2016 · 3 revisions

Separating Domain Code and Implementation Code

@ServiceMethod(callByContent=true)
public VehiclesTab startMyQoute() throws org.orm.PersistentException {
    PersistentTransaction t = autoinsurance.MetaworksapptemplatePersistentManager.instance().getSession().beginTransaction();
    try {
        getPolicyholder().save();
        VehiclesTab vehiclesTab = new VehiclesTab();
        vehiclesTab.setPolicyholder(getPolicyholder());
        t.commit();
        return vehiclesTab;
    }
    catch (Exception e) {
        t.rollback();
        throw new PersistenceException("고객정보입력시 오류", e);
    }
}

Way 1

Separation by abstract class

package com.abc.insurance;

import org.orm.PersistentTransaction;

public abstract class TransactionalBlock {

    public abstract void logic() throws Exception;

    public void run() throws Exception{
        PersistentTransaction t = AutoinsurancePersistentManager.instance().getSession().beginTransaction();
        try {

            logic();

            t.commit();
        }
        catch (Exception e) {
            e.printStackTrace();
            t.rollback();
        }

    }
}

business code will be changed like follows:

@ServiceMethod(callByContent=true)
public VehiclesTab startMyQoute() throws org.orm.PersistentException {
    new TransactionalBlock(){
       @Override
        public void logic() throws Exception{
            getPolicyholder().save();
            VehiclesTab vehiclesTab = new VehiclesTab();
            vehiclesTab.setPolicyholder(getPolicyholder());
        }
    }.run();
}

Way 2: Using AOP

declare Annotations and Advices

package framework;

  ...
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedTransaction {
}
package framework;

...
@Aspect
@Component
public class TransactionAdvice {

    @Before("@annotation(framework.NeedTransaction)")
    public void initiateTransaction() throws PersistentException {
        System.out.println("start tx");
        AutoinsurancePersistentManager.instance().getSession().beginTransaction();
    }

    @AfterReturning("@annotation(framework.NeedTransaction)")
    public void commitTransaction() throws Exception {
        System.out.println("commit");
        AutoinsurancePersistentManager.instance().getSession().getTransaction().commit();
    }

    @AfterThrowing("@annotation(framework.NeedTransaction)")
    public void rollbackTransaction() throws Exception {
        System.out.println("rollback");
        AutoinsurancePersistentManager.instance().getSession().getTransaction().rollback();
    }
}

business code will be changed like follows:

@Component
public class NameAndAddressTab {
….
@ServiceMethod(callByContent=true)
@NeedTransaction
public VehiclesTab startMyQoute() throws org.orm.PersistentException {
    getPolicyholder().save();
    VehiclesTab vehiclesTab = new VehiclesTab();
    vehiclesTab.setPolicyholder(getPolicyholder());
    return vehiclesTab;
}

[Note] Spring settings and versions

In order to place your codes under the effect of spring AOP container, your applicationContext.xml must be like this:

    <context:component-scan base-package="com.abc" />
    <context:component-scan base-package="framework" />
	<context:annotation-config />
	<aop:aspectj-autoproxy />

Also, your Spring and AspectJ versions should be like or above this:

Spring :  4.1.4.RELEASE
AspectJ:  1.7.2