replaced hibernate with eclipselink and fix jobschedule bug

1.replaced hibernate with eclipselink to comply with APL2
2.fix jobschedule bug
3.update ut

Author: ahutsunshine <[email protected]>
Author: He Wang <[email protected]>
Author: dodobel <[email protected]>

Closes #238 from ahutsunshine/master.


Project: http://git-wip-us.apache.org/repos/asf/incubator-griffin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-griffin/commit/4aab9d53
Tree: http://git-wip-us.apache.org/repos/asf/incubator-griffin/tree/4aab9d53
Diff: http://git-wip-us.apache.org/repos/asf/incubator-griffin/diff/4aab9d53

Branch: refs/heads/master
Commit: 4aab9d53319795ab14605309ffea2e05e9dfb282
Parents: 9ae7868
Author: ahutsunshine <[email protected]>
Authored: Wed Mar 28 17:41:04 2018 +0800
Committer: Lionel Liu <[email protected]>
Committed: Wed Mar 28 17:41:04 2018 +0800

----------------------------------------------------------------------
 service/pom.xml                                 |  60 +++++-
 .../core/config/EclipseLinkJpaConfig.java       |  41 ++++
 .../core/interceptor/TokenInterceptor.java      |  38 ++--
 .../apache/griffin/core/job/JobInstance.java    |  31 +--
 .../apache/griffin/core/job/JobServiceImpl.java |  27 ++-
 .../griffin/core/job/entity/AbstractJob.java    |   6 +-
 .../griffin/core/job/entity/GriffinJob.java     |  21 +-
 .../griffin/core/job/entity/JobDataSegment.java |   6 +-
 .../core/job/entity/JobInstanceBean.java        |  25 ++-
 .../griffin/core/job/entity/JobSchedule.java    |  41 ++--
 .../core/job/entity/SegmentPredicate.java       |  46 +++--
 .../griffin/core/job/repo/JobInstanceRepo.java  |  16 +-
 .../measure/entity/AbstractAuditableEntity.java |   2 +-
 .../core/measure/entity/DataConnector.java      |  31 ++-
 .../core/measure/entity/EvaluateRule.java       |   4 -
 .../core/measure/entity/GriffinMeasure.java     |  40 ++--
 .../griffin/core/measure/entity/Measure.java    |   8 +-
 .../griffin/core/measure/entity/Rule.java       | 113 ++++++-----
 .../core/measure/repo/DataConnectorRepo.java    |   2 +-
 .../main/resources/application-dev.properties   |  76 ++++---
 .../main/resources/application-prod.properties  |  63 ++++--
 .../src/main/resources/application.properties   |  15 +-
 .../src/main/resources/init_quartz_postgres.sql | 203 +++++++++++++++++++
 service/src/main/resources/quartz.properties    |   2 +-
 .../config/EclipseLinkJpaConfigForTest.java     |  39 ++++
 .../core/config/PropertiesConfigTest.java       |   1 -
 .../core/job/JobInstanceBeanRepoTest.java       |  28 ++-
 .../griffin/core/job/JobInstanceTest.java       |   7 +-
 .../griffin/core/job/JobServiceImplTest.java    |  43 ++--
 .../core/job/repo/JobInstanceRepoTest.java      |  23 ++-
 .../griffin/core/job/repo/JobRepoTest.java      |  17 +-
 .../measure/repo/DataConnectorRepoTest.java     |  24 ++-
 .../core/measure/repo/MeasureRepoTest.java      |   3 +
 .../hive/HiveMetaStoreServiceImplTest.java      |   2 +-
 .../apache/griffin/core/util/EntityHelper.java  |   6 +-
 .../src/test/resources/application.properties   |  14 +-
 service/src/test/resources/quartz.properties    |   4 +-
 37 files changed, 827 insertions(+), 301 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/pom.xml
----------------------------------------------------------------------
diff --git a/service/pom.xml b/service/pom.xml
index eb1e066..e2d96ae 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -46,6 +46,7 @@ under the License.
         <mockito.version>1.10.19</mockito.version>
         
<spring-boot-maven-plugin.version>1.5.1.RELEASE</spring-boot-maven-plugin.version>
         <derby.version>10.14.1.0</derby.version>
+        <eclipselink.version>2.6.0</eclipselink.version>
     </properties>
 
     <repositories>
@@ -76,6 +77,31 @@ under the License.
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.hibernate</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.aspectj</groupId>
+                    <artifactId>aspectjrt</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aspects</artifactId>
+        </dependency>
+        <!--eclipse link-->
+        <!--<dependency>-->
+        <!--<groupId>javax.persistence</groupId>-->
+        <!--<artifactId>javax.persistence-api</artifactId>-->
+        <!--<version>2.2</version>-->
+        <!--</dependency>-->
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>org.eclipse.persistence.jpa</artifactId>
+            <version>${eclipselink.version}</version>
         </dependency>
 
         <dependency>
@@ -84,15 +110,13 @@ under the License.
         </dependency>
 
         <!--prod db-->
+        <!--<dependency>-->
+        <!--<groupId>mysql</groupId>-->
+        <!--<artifactId>mysql-connector-java</artifactId>-->
+        <!--</dependency>-->
         <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.derby</groupId>
-            <artifactId>derbyclient</artifactId>
-            <version>${derby.version}</version>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
         </dependency>
 
         <dependency>
@@ -190,6 +214,26 @@ under the License.
     <build>
         <plugins>
             <plugin>
+                <groupId>com.ethlo.persistence.tools</groupId>
+                <artifactId>eclipselink-maven-plugin</artifactId>
+                <version>2.7.0</version>
+                <executions>
+                    <execution>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>weave</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.eclipse.persistence</groupId>
+                        <artifactId>org.eclipse.persistence.jpa</artifactId>
+                        <version>${eclipselink.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <version>${spring-boot-maven-plugin.version}</version>

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/config/EclipseLinkJpaConfig.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/config/EclipseLinkJpaConfig.java
 
b/service/src/main/java/org/apache/griffin/core/config/EclipseLinkJpaConfig.java
new file mode 100644
index 0000000..71341b0
--- /dev/null
+++ 
b/service/src/main/java/org/apache/griffin/core/config/EclipseLinkJpaConfig.java
@@ -0,0 +1,41 @@
+package org.apache.griffin.core.config;
+
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
+import 
org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
+import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
+import org.springframework.transaction.jta.JtaTransactionManager;
+
+import javax.sql.DataSource;
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+@ComponentScan("org.apache.griffin.core")
+public class EclipseLinkJpaConfig extends JpaBaseConfiguration {
+    protected EclipseLinkJpaConfig(DataSource ds, JpaProperties properties,
+                                   ObjectProvider<JtaTransactionManager> jtm,
+                                   
ObjectProvider<TransactionManagerCustomizers> tmc) {
+        super(ds, properties, jtm, tmc);
+    }
+
+    @Override
+    protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
+        return new EclipseLinkJpaVendorAdapter();
+    }
+
+    @Override
+    protected Map<String, Object> getVendorProperties() {
+        Map<String, Object> map = new HashMap<>();
+        map.put(PersistenceUnitProperties.WEAVING, "false");
+        map.put(PersistenceUnitProperties.DDL_GENERATION, 
"create-or-extend-tables");
+//        map.put("eclipselink.logging.level", "FINEST");
+//        map.put("eclipselink.logging.parameters", "true");
+        return map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/interceptor/TokenInterceptor.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/interceptor/TokenInterceptor.java
 
b/service/src/main/java/org/apache/griffin/core/interceptor/TokenInterceptor.java
index 2e1ea39..e5b9fdd 100644
--- 
a/service/src/main/java/org/apache/griffin/core/interceptor/TokenInterceptor.java
+++ 
b/service/src/main/java/org/apache/griffin/core/interceptor/TokenInterceptor.java
@@ -39,9 +39,12 @@ public class TokenInterceptor extends 
HandlerInterceptorAdapter {
             Method method = ((HandlerMethod) handler).getMethod();
             Token annotation = method.getAnnotation(Token.class);
             if (annotation != null) {
+                LOGGER.info("enter interceptor");
                 if (isRepeatSubmit(request)) {
                     LOGGER.warn("Please don't repeat submit url {}.", 
request.getServletPath());
                     return false;
+                } else {
+                    LOGGER.info("not repeat submit");
                 }
                 return true;
             }
@@ -53,22 +56,23 @@ public class TokenInterceptor extends 
HandlerInterceptorAdapter {
     }
 
     private boolean isRepeatSubmit(HttpServletRequest request) {
-        String curToken = request.getHeader(TOKEN);
-        HttpSession session = request.getSession();
-        Object preToken = session.getAttribute(TOKEN);
-        //if http header has no token,we ignore to deal with repeated 
submission.
-        if (curToken == null) {
-            return false;
-        } else if (preToken == null) {
-            session.setAttribute(TOKEN, curToken);
-            return false;
-        } else {
-            if (preToken.toString().equals(curToken)) {
-                return true;
-            } else {
-                session.setAttribute(TOKEN, curToken);
-                return false;
-            }
-        }
+//        String curToken = request.getHeader(TOKEN);
+//        HttpSession session = request.getSession(true);
+//        Object preToken = session.getAttribute(TOKEN);
+//        //if http header has no token,we ignore to deal with repeated 
submission.
+//        if (curToken == null) {
+//            return false;
+//        } else if (preToken == null) {
+//            session.setAttribute(TOKEN, curToken);
+//            return false;
+//        } else {
+//            if (preToken.toString().equals(curToken)) {
+//                return true;
+//            } else {
+//                session.setAttribute(TOKEN, curToken);
+//                return false;
+//            }
+//        }
+        return false;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/job/JobInstance.java
----------------------------------------------------------------------
diff --git a/service/src/main/java/org/apache/griffin/core/job/JobInstance.java 
b/service/src/main/java/org/apache/griffin/core/job/JobInstance.java
index f30bc0e..00becda 100644
--- a/service/src/main/java/org/apache/griffin/core/job/JobInstance.java
+++ b/service/src/main/java/org/apache/griffin/core/job/JobInstance.java
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import org.apache.commons.lang.StringUtils;
 import org.apache.griffin.core.job.entity.*;
 import org.apache.griffin.core.job.repo.GriffinJobRepo;
+import org.apache.griffin.core.job.repo.JobInstanceRepo;
 import org.apache.griffin.core.job.repo.JobScheduleRepo;
 import org.apache.griffin.core.measure.entity.DataConnector;
 import org.apache.griffin.core.measure.entity.DataSource;
@@ -67,6 +68,8 @@ public class JobInstance implements Job {
     @Autowired
     private JobScheduleRepo jobScheduleRepo;
     @Autowired
+    private JobInstanceRepo instanceRepo;
+    @Autowired
     @Qualifier("appConf")
     private Properties appConfProps;
 
@@ -114,7 +117,7 @@ public class JobInstance implements Job {
     private void setSourcesPartitionsAndPredicates(List<DataSource> sources) 
throws Exception {
         boolean isFirstBaseline = true;
         for (JobDataSegment jds : jobSchedule.getSegments()) {
-            if (jds.getBaseline() && isFirstBaseline) {
+            if (jds.isBaseline() && isFirstBaseline) {
                 Long tsOffset = 
TimeUtil.str2Long(jds.getSegmentRange().getBegin());
                 measure.setTimestamp(jobStartTime + tsOffset);
                 isFirstBaseline = false;
@@ -146,7 +149,7 @@ public class JobInstance implements Job {
      * split data into several part and get every part start timestamp
      *
      * @param segRange config of data
-     * @param dc data connector
+     * @param dc       data connector
      * @return split timestamps of data
      */
     private Long[] genSampleTs(SegmentRange segRange, DataConnector dc) {
@@ -174,32 +177,32 @@ public class JobInstance implements Job {
     /**
      * set data connector predicates
      *
-     * @param dc data connector
+     * @param dc       data connector
      * @param sampleTs collection of data split start timestamp
      */
-    private void setConnectorPredicates(DataConnector dc, Long[] sampleTs) 
throws IOException {
+    private void setConnectorPredicates(DataConnector dc, Long[] sampleTs){
         List<SegmentPredicate> predicates = dc.getPredicates();
         for (SegmentPredicate predicate : predicates) {
-            genConfMap(predicate.getConfigMap(), 
sampleTs,dc.getDataTimeZone());
+            genConfMap(predicate.getConfigMap(), sampleTs, 
dc.getDataTimeZone());
             //Do not forget to update origin string config
             predicate.setConfigMap(predicate.getConfigMap());
             mPredicates.add(predicate);
         }
     }
 
-    private void setConnectorConf(DataConnector dc, Long[] sampleTs) throws 
IOException {
-        genConfMap(dc.getConfigMap(), sampleTs,dc.getDataTimeZone());
+    private void setConnectorConf(DataConnector dc, Long[] sampleTs) {
+        genConfMap(dc.getConfigMap(), sampleTs, dc.getDataTimeZone());
         dc.setConfigMap(dc.getConfigMap());
     }
 
 
     /**
-     * @param conf    config map
+     * @param conf     config map
      * @param sampleTs collection of data split start timestamp
      * @return all config data combine,like {"where": "year=2017 AND month=11 
AND dt=15 AND hour=09,year=2017 AND month=11 AND dt=15 AND hour=10"}
      * or like {"path": 
"/year=2017/month=11/dt=15/hour=09/_DONE,/year=2017/month=11/dt=15/hour=10/_DONE"}
      */
-    private void genConfMap(Map<String, String> conf,  Long[] sampleTs,String 
timezone) {
+    private void genConfMap(Map<String, String> conf, Long[] sampleTs, String 
timezone) {
         if (conf == null) {
             LOGGER.warn("Predicate config is null.");
             return;
@@ -234,16 +237,16 @@ public class JobInstance implements Job {
         Scheduler scheduler = factory.getScheduler();
         TriggerKey triggerKey = triggerKey(jobName, groupName);
         return !(scheduler.checkExists(triggerKey)
-                || !saveGriffinJob(jobName, groupName)
+                || !saveJobInstance(jobName, groupName)
                 || !createJobInstance(triggerKey, interval, repeat, jobName));
     }
 
-    private boolean saveGriffinJob(String pName, String pGroup) {
-        List<JobInstanceBean> instances = griffinJob.getJobInstances();
+    private boolean saveJobInstance(String pName, String pGroup) {
         Long tms = System.currentTimeMillis();
         Long expireTms = 
Long.valueOf(appConfProps.getProperty("jobInstance.expired.milliseconds")) + 
tms;
-        instances.add(new JobInstanceBean(LivySessionStates.State.finding, 
pName, pGroup, tms, expireTms));
-        griffinJob = jobRepo.save(griffinJob);
+        JobInstanceBean instance = new 
JobInstanceBean(LivySessionStates.State.finding, pName, pGroup, tms, expireTms);
+        instance.setGriffinJob(griffinJob);
+        instanceRepo.save(instance);
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/job/JobServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/job/JobServiceImpl.java 
b/service/src/main/java/org/apache/griffin/core/job/JobServiceImpl.java
index e671c47..f42bc5c 100644
--- a/service/src/main/java/org/apache/griffin/core/job/JobServiceImpl.java
+++ b/service/src/main/java/org/apache/griffin/core/job/JobServiceImpl.java
@@ -51,12 +51,19 @@ import java.util.*;
 
 import static java.util.TimeZone.getTimeZone;
 import static org.apache.griffin.core.exception.GriffinExceptionMessage.*;
+import static 
org.apache.griffin.core.job.entity.LivySessionStates.State.starting;
+import static 
org.apache.griffin.core.job.entity.LivySessionStates.State.not_started;
+import static 
org.apache.griffin.core.job.entity.LivySessionStates.State.recovering;
+import static 
org.apache.griffin.core.job.entity.LivySessionStates.State.running;
+import static org.apache.griffin.core.job.entity.LivySessionStates.State.idle;
+import static org.apache.griffin.core.job.entity.LivySessionStates.State.busy;
 import static org.quartz.CronExpression.isValidExpression;
 import static org.quartz.CronScheduleBuilder.cronSchedule;
 import static org.quartz.JobBuilder.newJob;
 import static org.quartz.JobKey.jobKey;
 import static org.quartz.TriggerBuilder.newTrigger;
 import static org.quartz.TriggerKey.triggerKey;
+import static org.apache.griffin.core.job.entity.LivySessionStates.State;
 
 @Service
 public class JobServiceImpl implements JobService {
@@ -140,12 +147,12 @@ public class JobServiceImpl implements JobService {
 
     @Override
     public JobSchedule getJobSchedule(String jobName) {
-        JobSchedule jobSchedule = jobScheduleRepo.findByJobName(jobName);
-        if (jobSchedule == null) {
+        List<GriffinJob> jobs = jobRepo.findByJobNameAndDeleted(jobName, 
false);
+        if (jobs.size() == 0) {
             LOGGER.warn("Job name {} does not exist.", jobName);
             throw new 
GriffinException.NotFoundException(JOB_NAME_DOES_NOT_EXIST);
         }
-        return jobSchedule;
+        return jobs.get(0).getJobSchedule();
     }
 
     @Override
@@ -160,11 +167,10 @@ public class JobServiceImpl implements JobService {
         if (factory.getScheduler().checkExists(triggerKey)) {
             throw new 
GriffinException.ConflictException(QUARTZ_JOB_ALREADY_EXIST);
         }
-        GriffinJob job = new GriffinJob(measure.getId(), js.getJobName(), 
qName, qGroup, false);
+        GriffinJob job = new GriffinJob(measure.getId(), js.getJobName(), 
qName, qGroup, js,false);
         job = jobRepo.save(job);
-        js = jobScheduleRepo.save(js);
         addJob(triggerKey, js, job);
-        return js;
+        return job.getJobSchedule();
     }
 
     private void addJob(TriggerKey triggerKey, JobSchedule js, GriffinJob job) 
throws Exception {
@@ -223,7 +229,7 @@ public class JobServiceImpl implements JobService {
 
     private boolean isValidBaseLine(List<JobDataSegment> segments) {
         for (JobDataSegment jds : segments) {
-            if (jds.getBaseline()) {
+            if (jds.isBaseline()) {
                 return true;
             }
         }
@@ -347,9 +353,9 @@ public class JobServiceImpl implements JobService {
     }
 
     private void deletePredicateJob(GriffinJob job) throws SchedulerException {
-        List<JobInstanceBean> instances = job.getJobInstances();
+        List<JobInstanceBean> instances = 
jobInstanceRepo.findByJobId(job.getId());
         for (JobInstanceBean instance : instances) {
-            if (!instance.getDeleted()) {
+            if (!instance.isDeleted()) {
                 deleteJob(instance.getPredicateGroup(), 
instance.getPredicateName());
                 instance.setDeleted(true);
                 if 
(instance.getState().equals(LivySessionStates.State.finding)) {
@@ -459,7 +465,8 @@ public class JobServiceImpl implements JobService {
 
     @Scheduled(fixedDelayString = "${jobInstance.fixedDelay.in.milliseconds}")
     public void syncInstancesOfAllJobs() {
-        List<JobInstanceBean> beans = jobInstanceRepo.findByActiveState();
+        State[] states = {starting, not_started, recovering, idle, running, 
busy};
+        List<JobInstanceBean> beans = 
jobInstanceRepo.findByActiveState(states);
         if (!CollectionUtils.isEmpty(beans)) {
             for (JobInstanceBean jobInstance : beans) {
                 syncInstancesOfJob(jobInstance);

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/job/entity/AbstractJob.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/job/entity/AbstractJob.java 
b/service/src/main/java/org/apache/griffin/core/job/entity/AbstractJob.java
index 21ceec9..7839315 100644
--- a/service/src/main/java/org/apache/griffin/core/job/entity/AbstractJob.java
+++ b/service/src/main/java/org/apache/griffin/core/job/entity/AbstractJob.java
@@ -36,7 +36,7 @@ public abstract class AbstractJob extends 
AbstractAuditableEntity {
 
     protected String metricName;
 
-    protected Boolean deleted = false;
+    protected boolean deleted = false;
 
     AbstractJob() {
     }
@@ -77,11 +77,11 @@ public abstract class AbstractJob extends 
AbstractAuditableEntity {
         this.measureId = measureId;
     }
 
-    public Boolean getDeleted() {
+    public boolean isDeleted() {
         return deleted;
     }
 
-    public void setDeleted(Boolean deleted) {
+    public void setDeleted(boolean deleted) {
         this.deleted = deleted;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/job/entity/GriffinJob.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/job/entity/GriffinJob.java 
b/service/src/main/java/org/apache/griffin/core/job/entity/GriffinJob.java
index ee5e107..fe9553c 100644
--- a/service/src/main/java/org/apache/griffin/core/job/entity/GriffinJob.java
+++ b/service/src/main/java/org/apache/griffin/core/job/entity/GriffinJob.java
@@ -33,9 +33,10 @@ public class GriffinJob extends AbstractJob {
     @Column(name = "quartz_group_name")
     private String quartzGroup;
 
-    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, 
CascadeType.REMOVE, CascadeType.MERGE}, orphanRemoval = true)
-    @JoinColumn(name = "job_id")
-    private List<JobInstanceBean> jobInstances = new ArrayList<>();
+
+    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+    @JoinColumn(name = "job_schedule_id")
+    private JobSchedule jobSchedule;
 
     public String getQuartzName() {
         return quartzName;
@@ -53,18 +54,24 @@ public class GriffinJob extends AbstractJob {
         this.quartzGroup = quartzGroup;
     }
 
-    public List<JobInstanceBean> getJobInstances() {
-        return jobInstances;
+    public JobSchedule getJobSchedule() {
+        return jobSchedule;
     }
 
-    public void setJobInstances(List<JobInstanceBean> jobInstances) {
-        this.jobInstances = jobInstances;
+    public void setJobSchedule(JobSchedule jobSchedule) {
+        this.jobSchedule = jobSchedule;
     }
 
+
     public GriffinJob() {
         super();
     }
 
+    public GriffinJob(Long measureId, String jobName, String quartzName, 
String quartzGroup, JobSchedule schedule,boolean deleted) {
+        this(measureId, jobName, quartzName, quartzGroup, deleted);
+        this.jobSchedule = schedule;
+    }
+
     public GriffinJob(Long measureId, String jobName, String quartzName, 
String quartzGroup, boolean deleted) {
         super(measureId, jobName, deleted);
         this.metricName = jobName;

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/job/entity/JobDataSegment.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/job/entity/JobDataSegment.java 
b/service/src/main/java/org/apache/griffin/core/job/entity/JobDataSegment.java
index c81c733..7b2b673 100644
--- 
a/service/src/main/java/org/apache/griffin/core/job/entity/JobDataSegment.java
+++ 
b/service/src/main/java/org/apache/griffin/core/job/entity/JobDataSegment.java
@@ -36,19 +36,19 @@ public class JobDataSegment extends AbstractAuditableEntity 
{
     @NotNull
     private String dataConnectorName;
 
-    private Boolean baseline = false;
+    private boolean baseline = false;
 
     @OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, 
CascadeType.REMOVE, CascadeType.MERGE})
     @JoinColumn(name = "segment_range_id")
     private SegmentRange segmentRange = new SegmentRange();
 
     @JsonProperty("as.baseline")
-    public Boolean getBaseline() {
+    public boolean isBaseline() {
         return baseline;
     }
 
     @JsonProperty("as.baseline")
-    public void setBaseline(Boolean baseline) {
+    public void setBaseline(boolean baseline) {
         this.baseline = baseline;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java 
b/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
index ff4d444..89e0e8a 100644
--- 
a/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
+++ 
b/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
@@ -23,10 +23,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import org.apache.griffin.core.job.entity.LivySessionStates.State;
 import org.apache.griffin.core.measure.entity.AbstractAuditableEntity;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
+import javax.persistence.*;
 
 @Entity
 public class JobInstanceBean extends AbstractAuditableEntity {
@@ -40,7 +37,7 @@ public class JobInstanceBean extends AbstractAuditableEntity {
 
     private String appId;
 
-    @Column(length = 10 * 1024)
+    @Column(length = 2 * 1024)
     private String appUri;
 
     @Column(name = "timestamp")
@@ -56,7 +53,11 @@ public class JobInstanceBean extends AbstractAuditableEntity 
{
     private String predicateName;
 
     @Column(name = "predicate_job_deleted")
-    private Boolean deleted = false;
+    private boolean deleted = false;
+
+    @ManyToOne
+    @JoinColumn(name = "job_id",nullable = false)
+    private GriffinJob griffinJob;
 
     public Long getSessionId() {
         return sessionId;
@@ -126,14 +127,22 @@ public class JobInstanceBean extends 
AbstractAuditableEntity {
         this.predicateName = predicateName;
     }
 
-    public Boolean getDeleted() {
+    public boolean isDeleted() {
         return deleted;
     }
 
-    public void setDeleted(Boolean deleted) {
+    public void setDeleted(boolean deleted) {
         this.deleted = deleted;
     }
 
+    public GriffinJob getGriffinJob() {
+        return griffinJob;
+    }
+
+    public void setGriffinJob(GriffinJob griffinJob) {
+        this.griffinJob = griffinJob;
+    }
+
     public JobInstanceBean() {
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/job/entity/JobSchedule.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/job/entity/JobSchedule.java 
b/service/src/main/java/org/apache/griffin/core/job/entity/JobSchedule.java
index 5116805..c71b6d8 100644
--- a/service/src/main/java/org/apache/griffin/core/job/entity/JobSchedule.java
+++ b/service/src/main/java/org/apache/griffin/core/job/entity/JobSchedule.java
@@ -55,7 +55,7 @@ public class JobSchedule extends AbstractAuditableEntity {
     private String timeZone;
 
     @JsonIgnore
-    @Access(AccessType.PROPERTY)
+//    @Access(AccessType.PROPERTY)
     private String predicateConfig;
 
     @Transient
@@ -124,27 +124,38 @@ public class JobSchedule extends AbstractAuditableEntity {
         this.segments = segments;
     }
 
+    @JsonProperty("predicate.config")
+    public Map<String, Object> getConfigMap() {
+        return configMap;
+    }
+
+    @JsonProperty("predicate.config")
+    public void setConfigMap(Map<String, Object> configMap) {
+        this.configMap = configMap;
+    }
+
     private String getPredicateConfig() {
         return predicateConfig;
     }
 
-    private void setPredicateConfig(String config) throws IOException {
-        if (!StringUtils.isEmpty(config)) {
-            this.predicateConfig = config;
-            this.configMap = JsonUtil.toEntity(config, new 
TypeReference<Map<String, Object>>() {
-            });
-        }
+    private void setPredicateConfig(String config) {
+        this.predicateConfig = config;
     }
 
-    @JsonProperty("predicate.config")
-    public Map<String, Object> getConfigMap() {
-        return configMap;
+    @PrePersist
+    @PreUpdate
+    public void save() throws JsonProcessingException {
+        if (configMap != null) {
+            this.predicateConfig = JsonUtil.toJson(configMap);
+        }
     }
 
-    @JsonProperty("predicate.config")
-    private void setConfigMap(Map<String, Object> configMap) throws 
JsonProcessingException {
-        this.configMap = configMap;
-        this.predicateConfig = JsonUtil.toJson(configMap);
+    @PostLoad
+    public void load() throws IOException {
+        if (!StringUtils.isEmpty(predicateConfig)) {
+            this.configMap = JsonUtil.toEntity(predicateConfig, new 
TypeReference<Map<String, Object>>() {
+            });
+        }
     }
 
     /**
@@ -159,7 +170,7 @@ public class JobSchedule extends AbstractAuditableEntity {
         map.put("interval", appConf.getProperty("predicate.job.interval"));
         map.put("repeat", appConf.getProperty("predicate.job.repeat.count"));
         scheduleConf.put("checkdonefile.schedule", map);
-        setConfigMap(scheduleConf);
+        this.predicateConfig = JsonUtil.toJson(scheduleConf);
         return scheduleConf;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/job/entity/SegmentPredicate.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/job/entity/SegmentPredicate.java
 
b/service/src/main/java/org/apache/griffin/core/job/entity/SegmentPredicate.java
index ac51f97..dafba89 100644
--- 
a/service/src/main/java/org/apache/griffin/core/job/entity/SegmentPredicate.java
+++ 
b/service/src/main/java/org/apache/griffin/core/job/entity/SegmentPredicate.java
@@ -28,10 +28,7 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.griffin.core.measure.entity.AbstractAuditableEntity;
 import org.apache.griffin.core.util.JsonUtil;
 
-import javax.persistence.Access;
-import javax.persistence.AccessType;
-import javax.persistence.Entity;
-import javax.persistence.Transient;
+import javax.persistence.*;
 import java.io.IOException;
 import java.util.Map;
 
@@ -41,7 +38,7 @@ public class SegmentPredicate extends AbstractAuditableEntity 
{
     private String type;
 
     @JsonIgnore
-    @Access(AccessType.PROPERTY)
+//    @Access(AccessType.PROPERTY)
     private String config;
 
     @Transient
@@ -55,27 +52,38 @@ public class SegmentPredicate extends 
AbstractAuditableEntity {
         this.type = type;
     }
 
+    @JsonProperty("config")
+    public Map<String, String> getConfigMap() {
+        return configMap;
+    }
+
+    @JsonProperty("config")
+    public void setConfigMap(Map<String, String> configMap) {
+        this.configMap = configMap;
+    }
+
     public String getConfig() {
         return config;
     }
 
-    public void setConfig(String config) throws IOException {
-        if (!StringUtils.isEmpty(config)) {
-            this.config = config;
-            this.configMap = JsonUtil.toEntity(config, new 
TypeReference<Map<String, String>>() {
-            });
-        }
+    public void setConfig(String config) {
+        this.config = config;
     }
 
-    @JsonProperty("config")
-    public Map<String, String> getConfigMap(){
-        return configMap;
+    @PrePersist
+    @PreUpdate
+    public void save() throws JsonProcessingException {
+        if (configMap != null) {
+            this.config = JsonUtil.toJson(configMap);
+        }
     }
 
-    @JsonProperty("config")
-    public void setConfigMap(Map<String, String> configMap) throws 
JsonProcessingException {
-        this.configMap = configMap;
-        this.config = JsonUtil.toJson(configMap);
+    @PostLoad
+    public void load() throws IOException {
+        if (!StringUtils.isEmpty(config)) {
+            this.configMap = JsonUtil.toEntity(config, new 
TypeReference<Map<String, Object>>() {
+            });
+        }
     }
 
     public SegmentPredicate() {
@@ -83,6 +91,6 @@ public class SegmentPredicate extends AbstractAuditableEntity 
{
 
     public SegmentPredicate(String type, Map configMap) throws 
JsonProcessingException {
         this.type = type;
-        setConfigMap(configMap);
+        this.config = JsonUtil.toJson(configMap);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/job/repo/JobInstanceRepo.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/job/repo/JobInstanceRepo.java 
b/service/src/main/java/org/apache/griffin/core/job/repo/JobInstanceRepo.java
index c873a97..d55d27d 100644
--- 
a/service/src/main/java/org/apache/griffin/core/job/repo/JobInstanceRepo.java
+++ 
b/service/src/main/java/org/apache/griffin/core/job/repo/JobInstanceRepo.java
@@ -27,17 +27,22 @@ import 
org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 
+import static org.apache.griffin.core.job.entity.LivySessionStates.State;
+
 public interface JobInstanceRepo extends CrudRepository<JobInstanceBean, Long> 
{
 
-    @Query("select DISTINCT s from JobInstanceBean s " +
-            "where s.state in ('starting', 'not_started', 'recovering', 
'idle', 'running', 'busy')")
-    List<JobInstanceBean> findByActiveState();
+//    @Query("select DISTINCT s from JobInstanceBean s " +
+//            "where s.state in ('starting', 'not_started', 'recovering', 
'idle', 'running', 'busy')")
+//    List<JobInstanceBean> findByActiveState();
 
     JobInstanceBean findByPredicateName(String name);
 
-    @Query("select s from JobInstanceBean s where job_id = ?1")
+    @Query("select s from JobInstanceBean s where s.griffinJob.id = ?1")
     List<JobInstanceBean> findByJobId(Long jobId, Pageable pageable);
 
+    @Query("select s from JobInstanceBean s where s.griffinJob.id = ?1")
+    List<JobInstanceBean> findByJobId(Long jobId);
+
     List<JobInstanceBean> findByExpireTmsLessThanEqual(Long expireTms);
 
     @Transactional(rollbackFor = Exception.class)
@@ -45,4 +50,7 @@ public interface JobInstanceRepo extends 
CrudRepository<JobInstanceBean, Long> {
     @Query("delete from JobInstanceBean j where j.expireTms <= ?1")
     int deleteByExpireTimestamp(Long expireTms);
 
+    @Query("select DISTINCT s from JobInstanceBean s " +
+            "where s.state in ?1")
+    List<JobInstanceBean> findByActiveState(State[] states);
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/measure/entity/AbstractAuditableEntity.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/entity/AbstractAuditableEntity.java
 
b/service/src/main/java/org/apache/griffin/core/measure/entity/AbstractAuditableEntity.java
index 72125de..4bda504 100644
--- 
a/service/src/main/java/org/apache/griffin/core/measure/entity/AbstractAuditableEntity.java
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/entity/AbstractAuditableEntity.java
@@ -35,7 +35,7 @@ public abstract class AbstractAuditableEntity implements 
Serializable {
 
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
-    private Long id;
+    protected Long id;
 
     @JsonIgnore
     private Long createdDate = System.currentTimeMillis();

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/measure/entity/DataConnector.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/entity/DataConnector.java
 
b/service/src/main/java/org/apache/griffin/core/measure/entity/DataConnector.java
index d126f5b..532cb48 100644
--- 
a/service/src/main/java/org/apache/griffin/core/measure/entity/DataConnector.java
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/entity/DataConnector.java
@@ -61,7 +61,7 @@ public class DataConnector extends AbstractAuditableEntity {
     private String defaultDataUnit = "365000d";
 
     @JsonIgnore
-    @Access(AccessType.PROPERTY)
+//    @Access(AccessType.PROPERTY)
     private String config;
 
     @Transient
@@ -85,17 +85,12 @@ public class DataConnector extends AbstractAuditableEntity {
     }
 
     @JsonProperty("config")
-    public void setConfigMap(Map<String, String> configMap) throws 
JsonProcessingException {
+    public void setConfigMap(Map<String, String> configMap) {
         this.configMap = configMap;
-        this.config = JsonUtil.toJson(configMap);
     }
 
-    public void setConfig(String config) throws IOException {
-        if (!StringUtils.isEmpty(config)) {
-            this.config = config;
-            this.configMap = JsonUtil.toEntity(config, new 
TypeReference<Map<String, String>>() {
-            });
-        }
+    public void setConfig(String config) {
+        this.config = config;
     }
 
     public String getConfig() {
@@ -158,6 +153,22 @@ public class DataConnector extends AbstractAuditableEntity 
{
         this.version = version;
     }
 
+    @PrePersist
+    @PreUpdate
+    public void save() throws JsonProcessingException {
+        if (configMap != null) {
+            this.config = JsonUtil.toJson(configMap);
+        }
+    }
+
+    @PostLoad
+    public void load() throws IOException {
+        if (!org.springframework.util.StringUtils.isEmpty(config)) {
+            this.configMap = JsonUtil.toEntity(config, new 
TypeReference<Map<String, Object>>() {
+            });
+        }
+    }
+
 
     public DataConnector() {
     }
@@ -171,7 +182,7 @@ public class DataConnector extends AbstractAuditableEntity {
         });
     }
 
-    public DataConnector(String name, String dataUnit, Map configMap, 
List<SegmentPredicate> predicates) throws IOException {
+    public DataConnector(String name, String dataUnit, Map<String,String> 
configMap, List<SegmentPredicate> predicates) {
         this.name = name;
         this.dataUnit = dataUnit;
         this.configMap = configMap;

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/measure/entity/EvaluateRule.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/entity/EvaluateRule.java
 
b/service/src/main/java/org/apache/griffin/core/measure/entity/EvaluateRule.java
index 75a39ce..1ad64da 100644
--- 
a/service/src/main/java/org/apache/griffin/core/measure/entity/EvaluateRule.java
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/entity/EvaluateRule.java
@@ -20,9 +20,6 @@ under the License.
 package org.apache.griffin.core.measure.entity;
 
 
-import org.hibernate.annotations.Fetch;
-import org.hibernate.annotations.FetchMode;
-
 import javax.persistence.*;
 import java.util.ArrayList;
 import java.util.List;
@@ -34,7 +31,6 @@ public class EvaluateRule extends AbstractAuditableEntity {
 
     @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, 
CascadeType.REMOVE, CascadeType.MERGE})
     @JoinColumn(name = "evaluateRule_id")
-    @Fetch(FetchMode.SUBSELECT)
     private List<Rule> rules = new ArrayList<>();
 
     public List<Rule> getRules() {

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/measure/entity/GriffinMeasure.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/entity/GriffinMeasure.java
 
b/service/src/main/java/org/apache/griffin/core/measure/entity/GriffinMeasure.java
index d597a6d..23dfc37 100644
--- 
a/service/src/main/java/org/apache/griffin/core/measure/entity/GriffinMeasure.java
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/entity/GriffinMeasure.java
@@ -48,7 +48,7 @@ public class GriffinMeasure extends Measure {
     private Long timestamp;
 
     @JsonIgnore
-    @Access(AccessType.PROPERTY)
+//    @Access(AccessType.PROPERTY)
     @Column(length = 1024)
     private String ruleDescription;
 
@@ -102,27 +102,23 @@ public class GriffinMeasure extends Measure {
         this.evaluateRule = evaluateRule;
     }
 
-    public String getRuleDescription() {
-        return ruleDescription;
-    }
-
-    public void setRuleDescription(String ruleDescription) throws IOException {
-        if (!StringUtils.isEmpty(ruleDescription)) {
-            this.ruleDescription = ruleDescription;
-            this.ruleDescriptionMap = JsonUtil.toEntity(ruleDescription, new 
TypeReference<Map<String, Object>>() {
-            });
-        }
-    }
-
     @JsonProperty("rule.description")
     public Map<String, Object> getRuleDescriptionMap() {
         return ruleDescriptionMap;
     }
 
     @JsonProperty("rule.description")
-    public void setRuleDescriptionMap(Map<String, Object> ruleDescriptionMap) 
throws JsonProcessingException {
+    public void setRuleDescriptionMap(Map<String, Object> ruleDescriptionMap) {
         this.ruleDescriptionMap = ruleDescriptionMap;
-        this.ruleDescription = JsonUtil.toJson(ruleDescriptionMap);
+    }
+
+
+    public String getRuleDescription() {
+        return ruleDescription;
+    }
+
+    public void setRuleDescription(String ruleDescription) {
+        this.ruleDescription = ruleDescription;
     }
 
     public Long getTimestamp() {
@@ -157,4 +153,18 @@ public class GriffinMeasure extends Measure {
         this.evaluateRule = evaluateRule;
     }
 
+    @PrePersist
+    @PreUpdate
+    public void save() throws JsonProcessingException {
+        if (ruleDescriptionMap != null) {
+            this.ruleDescription = JsonUtil.toJson(ruleDescriptionMap);
+        }
+    }
+    @PostLoad
+    public void load() throws IOException {
+        if (!StringUtils.isEmpty(ruleDescription)) {
+            this.ruleDescriptionMap = JsonUtil.toEntity(ruleDescription, new 
TypeReference<Map<String, Object>>() {
+            });
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/measure/entity/Measure.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/entity/Measure.java 
b/service/src/main/java/org/apache/griffin/core/measure/entity/Measure.java
index 4ccc75f..af2efc4 100644
--- a/service/src/main/java/org/apache/griffin/core/measure/entity/Measure.java
+++ b/service/src/main/java/org/apache/griffin/core/measure/entity/Measure.java
@@ -46,7 +46,7 @@ public abstract class Measure extends AbstractAuditableEntity 
{
 
     private String organization;
 
-    private Boolean deleted = false;
+    private boolean deleted = false;
 
     public String getName() {
         return name;
@@ -90,11 +90,11 @@ public abstract class Measure extends 
AbstractAuditableEntity {
         this.owner = owner;
     }
 
-    public Boolean getDeleted() {
-        return this.deleted;
+    public boolean isDeleted() {
+        return deleted;
     }
 
-    public void setDeleted(Boolean deleted) {
+    public void setDeleted(boolean deleted) {
         this.deleted = deleted;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/measure/entity/Rule.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/entity/Rule.java 
b/service/src/main/java/org/apache/griffin/core/measure/entity/Rule.java
index a7b424d..8207f74 100644
--- a/service/src/main/java/org/apache/griffin/core/measure/entity/Rule.java
+++ b/service/src/main/java/org/apache/griffin/core/measure/entity/Rule.java
@@ -25,7 +25,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import org.apache.griffin.core.util.JsonUtil;
-import org.springframework.util.StringUtils;
 
 import javax.persistence.*;
 import javax.validation.constraints.NotNull;
@@ -52,7 +51,7 @@ public class Rule extends AbstractAuditableEntity {
     private String name;
 
     @JsonIgnore
-    @Access(AccessType.PROPERTY)
+//    @Access(AccessType.PROPERTY)
     @Column(length = 1024)
     private String details;
 
@@ -61,7 +60,7 @@ public class Rule extends AbstractAuditableEntity {
     private Map<String, Object> detailsMap;
 
     @JsonIgnore
-    @Access(AccessType.PROPERTY)
+//    @Access(AccessType.PROPERTY)
     private String metric;
 
     @Transient
@@ -69,7 +68,7 @@ public class Rule extends AbstractAuditableEntity {
     private Map<String, Object> metricMap;
 
     @JsonIgnore
-    @Access(AccessType.PROPERTY)
+//    @Access(AccessType.PROPERTY)
     private String record;
 
     @Transient
@@ -104,39 +103,14 @@ public class Rule extends AbstractAuditableEntity {
         this.rule = rule;
     }
 
-    public String getDetails() {
-        return details;
-    }
-
-    private void setDetails(String details) throws IOException {
-        if (!StringUtils.isEmpty(details)) {
-            this.details = details;
-            this.detailsMap = JsonUtil.toEntity(details, new 
TypeReference<Map<String, Object>>() {
-            });
-        }
-    }
-
     @JsonProperty("details")
     public Map<String, Object> getDetailsMap() {
         return detailsMap;
     }
 
     @JsonProperty("details")
-    public void setDetailsMap(Map<String, Object> details) throws IOException {
-        this.detailsMap = details;
-        this.details = JsonUtil.toJson(details);
-    }
-
-    public String getMetric() {
-        return metric;
-    }
-
-    public void setMetric(String metric) throws IOException {
-        if (!StringUtils.isEmpty(metric)) {
-            this.metric = metric;
-            this.metricMap = JsonUtil.toEntity(metric, new 
TypeReference<Map<String, Object>>() {
-            });
-        }
+    public void setDetailsMap(Map<String, Object> detailsMap) {
+        this.detailsMap = detailsMap;
     }
 
     @JsonProperty("metric")
@@ -145,21 +119,8 @@ public class Rule extends AbstractAuditableEntity {
     }
 
     @JsonProperty("metric")
-    public void setMetricMap(Map<String, Object> metricMap) throws 
JsonProcessingException {
+    public void setMetricMap(Map<String, Object> metricMap) {
         this.metricMap = metricMap;
-        this.metric = JsonUtil.toJson(metricMap);
-    }
-
-    public String getRecord() {
-        return record;
-    }
-
-    public void setRecord(String record) throws IOException {
-        if (!StringUtils.isEmpty(record)) {
-            this.record = record;
-            this.recordMap = JsonUtil.toEntity(record, new 
TypeReference<Map<String, Object>>() {
-            });
-        }
     }
 
     @JsonProperty("record")
@@ -168,9 +129,32 @@ public class Rule extends AbstractAuditableEntity {
     }
 
     @JsonProperty("record")
-    public void setRecordMap(Map<String, Object> recordMap) throws 
JsonProcessingException {
+    public void setRecordMap(Map<String, Object> recordMap) {
         this.recordMap = recordMap;
-        this.record = JsonUtil.toJson(recordMap);
+    }
+
+    public String getDetails() {
+        return details;
+    }
+
+    private void setDetails(String details) {
+        this.details = details;
+    }
+
+    public String getMetric() {
+        return metric;
+    }
+
+    public void setMetric(String metric) {
+        this.metric = metric;
+    }
+
+    public String getRecord() {
+        return record;
+    }
+
+    public void setRecord(String record) {
+        this.record = record;
     }
 
     public String getName() {
@@ -181,13 +165,44 @@ public class Rule extends AbstractAuditableEntity {
         this.name = name;
     }
 
+    @PrePersist
+    @PreUpdate
+    public void save() throws JsonProcessingException {
+        if (detailsMap != null) {
+            this.details = JsonUtil.toJson(detailsMap);
+        }
+        if (metricMap != null) {
+            this.metric = JsonUtil.toJson(metricMap);
+        }
+        if (recordMap != null) {
+            this.record = JsonUtil.toJson(recordMap);
+        }
+
+    }
+
+    @PostLoad
+    public void load() throws IOException {
+        if (!org.springframework.util.StringUtils.isEmpty(details)) {
+            this.detailsMap = JsonUtil.toEntity(details, new 
TypeReference<Map<String, Object>>() {
+            });
+        }
+        if (!org.springframework.util.StringUtils.isEmpty(metric)) {
+            this.metricMap = JsonUtil.toEntity(metric, new 
TypeReference<Map<String, Object>>() {
+            });
+        }
+        if (!org.springframework.util.StringUtils.isEmpty(record)) {
+            this.recordMap = JsonUtil.toEntity(record, new 
TypeReference<Map<String, Object>>() {
+            });
+        }
+    }
+
     public Rule() {
     }
 
-    public Rule(String dslType, String dqType, String rule, Map<String, 
Object> details) throws IOException {
+    public Rule(String dslType, String dqType, String rule, Map<String, 
Object> detailsMap) throws JsonProcessingException {
         this.dslType = dslType;
         this.dqType = dqType;
         this.rule = rule;
-        setDetailsMap(details);
+        this.details = JsonUtil.toJson(detailsMap);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
 
b/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
index 120a666..345f197 100644
--- 
a/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
@@ -27,6 +27,6 @@ import java.util.List;
 
 public interface DataConnectorRepo extends CrudRepository<DataConnector, Long> 
{
 
-    @Query("select dc from DataConnector dc where name in ?1")
+    @Query("select dc from DataConnector dc where dc.name in ?1")
     List<DataConnector> findByConnectorNames(List<String> names);
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/resources/application-dev.properties
----------------------------------------------------------------------
diff --git a/service/src/main/resources/application-dev.properties 
b/service/src/main/resources/application-dev.properties
index 057d412..741fe5e 100644
--- a/service/src/main/resources/application-dev.properties
+++ b/service/src/main/resources/application-dev.properties
@@ -17,35 +17,59 @@
 # under the License.
 #
 
-spring.datasource.url= 
jdbc:mysql://localhost:3306/quartz?autoReconnect=true&useSSL=false
-spring.datasource.username =griffin
-spring.datasource.password =123456
-spring.datasource.driver-class-name=com.mysql.jdbc.Driver
-
-# Hibernate ddl auto (validate,create, create-drop, update)
-spring.jpa.hibernate.ddl-auto = update
-spring.jpa.show-sql=true
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
-#
-#
-## Naming strategy
-spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
-
-# hive metastore
-# livy determine which spark to submit, spark knows which hive to get data, so 
if you change hive address here, you should check
-# livy.uri in sparkJob.properties to make the hive pointed by livy -> spark -> 
hive is this one you get info from.
-# Also check spark.uri in sparkJob.properties to make sure the link of 
application id belongs to right spark.
-#hive.metastore.uris = thrift://10.149.247.156:29083
-hive.metastore.uris = thrift://10.9.246.187:9083
+spring.datasource.url = 
jdbc:postgresql://localhost:5432/quartz?autoReconnect=true&useSSL=false
+spring.datasource.username = griffin
+spring.datasource.password = 123456
+spring.jpa.generate-ddl=true
+
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+spring.datasource.driverClassName = org.postgresql.Driver
+
+spring.jpa.show-sql = true
+
+#spring.jpa.properties.eclipselink.weaving=static
+#spring.jpa.properties.persistence-unit-name=eclipselink-example
+#spring.jpa.properties.persistence-xml-location=persistence.xml
+
+# Hive metastore
+hive.metastore.uris = thrift://localhost:9083
 hive.metastore.dbname = default
 hive.hmshandler.retry.attempts = 15
 hive.hmshandler.retry.interval = 2000ms
+# Hive cache time
+cache.evict.hive.fixedRate.in.milliseconds = 900000
+
+# Kafka schema registry
+kafka.schema.registry.url = http://localhost:8081
+
+# Update job instance state at regular intervals
+jobInstance.fixedDelay.in.milliseconds = 60000
+# Expired time of job instance which is 7 days that is 604800000 
milliseconds.Time unit only supports milliseconds
+jobInstance.expired.milliseconds = 604800000
+
+# schedule predicate job every 5 minutes and repeat 12 times at most
+#interval time unit s:second m:minute h:hour d:day,only support these four 
units
+predicate.job.interval = 5m
+predicate.job.repeat.count = 12
+
+# external properties directory location
+external.config.location =
+
+# login strategy ("default" or "ldap")
+login.strategy = default
 
-# kafka schema registry
-kafka.schema.registry.url = http://10.65.159.119:8081
+# ldap
+ldap.url = ldap://hostname:port
+ldap.email = @example.com
+ldap.searchBase = DC=org,DC=example
+ldap.searchPattern = (sAMAccountName={0})
 
-# jobInstance
-jobInstance.fixedDelay.in.milliseconds=60000
+# hdfs
+fs.defaultFS = hdfs://hdfs-default-name
 
-# spring cache
-cache.evict.hive.fixedRate.in.milliseconds=900000
\ No newline at end of file
+# elasticsearch
+elasticsearch.host = localhost
+elasticsearch.port = 9200
+elasticsearch.scheme = http
+# elasticsearch.user = user
+# elasticsearch.password = password
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/resources/application-prod.properties
----------------------------------------------------------------------
diff --git a/service/src/main/resources/application-prod.properties 
b/service/src/main/resources/application-prod.properties
index 107e56c..741fe5e 100644
--- a/service/src/main/resources/application-prod.properties
+++ b/service/src/main/resources/application-prod.properties
@@ -17,22 +17,59 @@
 # under the License.
 #
 
-spring.datasource.url= jdbc:mysql://localhost:3306/griffin
-spring.datasource.username =root
-spring.datasource.password =1qaz
-#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.url = 
jdbc:postgresql://localhost:5432/quartz?autoReconnect=true&useSSL=false
+spring.datasource.username = griffin
+spring.datasource.password = 123456
+spring.jpa.generate-ddl=true
 
-spring.jpa.hibernate.ddl-auto = update
-spring.jpa.show-sql=true
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+spring.datasource.driverClassName = org.postgresql.Driver
 
+spring.jpa.show-sql = true
 
-# Naming strategy
-spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
+#spring.jpa.properties.eclipselink.weaving=static
+#spring.jpa.properties.persistence-unit-name=eclipselink-example
+#spring.jpa.properties.persistence-xml-location=persistence.xml
 
-# hive metastore
-hive.metastore.uris = thrift://10.9.246.187:9083
+# Hive metastore
+hive.metastore.uris = thrift://localhost:9083
 hive.metastore.dbname = default
+hive.hmshandler.retry.attempts = 15
+hive.hmshandler.retry.interval = 2000ms
+# Hive cache time
+cache.evict.hive.fixedRate.in.milliseconds = 900000
 
-# kafka schema registry
-kafka.schema.registry.url = http://10.65.159.119:8081
\ No newline at end of file
+# Kafka schema registry
+kafka.schema.registry.url = http://localhost:8081
+
+# Update job instance state at regular intervals
+jobInstance.fixedDelay.in.milliseconds = 60000
+# Expired time of job instance which is 7 days that is 604800000 
milliseconds.Time unit only supports milliseconds
+jobInstance.expired.milliseconds = 604800000
+
+# schedule predicate job every 5 minutes and repeat 12 times at most
+#interval time unit s:second m:minute h:hour d:day,only support these four 
units
+predicate.job.interval = 5m
+predicate.job.repeat.count = 12
+
+# external properties directory location
+external.config.location =
+
+# login strategy ("default" or "ldap")
+login.strategy = default
+
+# ldap
+ldap.url = ldap://hostname:port
+ldap.email = @example.com
+ldap.searchBase = DC=org,DC=example
+ldap.searchPattern = (sAMAccountName={0})
+
+# hdfs
+fs.defaultFS = hdfs://hdfs-default-name
+
+# elasticsearch
+elasticsearch.host = localhost
+elasticsearch.port = 9200
+elasticsearch.scheme = http
+# elasticsearch.user = user
+# elasticsearch.password = password
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git a/service/src/main/resources/application.properties 
b/service/src/main/resources/application.properties
index b04f304..c8f1992 100644
--- a/service/src/main/resources/application.properties
+++ b/service/src/main/resources/application.properties
@@ -17,17 +17,18 @@
 # under the License.
 #
 
-spring.datasource.url = 
jdbc:mysql://localhost:3306/quartz?autoReconnect=true&useSSL=false
+spring.datasource.url = 
jdbc:postgresql://localhost:5432/quartz?autoReconnect=true&useSSL=false
 spring.datasource.username = griffin
 spring.datasource.password = 123456
-spring.datasource.driver-class-name = com.mysql.jdbc.Driver
+spring.jpa.generate-ddl=true
+
+spring.datasource.driverClassName = org.postgresql.Driver
 
-# Hibernate ddl auto (validate, create, create-drop, update)
-spring.jpa.hibernate.ddl-auto = update
 spring.jpa.show-sql = true
-spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
-# Naming strategy
-spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
+
+#spring.jpa.properties.eclipselink.weaving=static
+#spring.jpa.properties.persistence-unit-name=eclipselink-example
+#spring.jpa.properties.persistence-xml-location=persistence.xml
 
 # Hive metastore
 hive.metastore.uris = thrift://localhost:9083

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/resources/init_quartz_postgres.sql
----------------------------------------------------------------------
diff --git a/service/src/main/resources/init_quartz_postgres.sql 
b/service/src/main/resources/init_quartz_postgres.sql
new file mode 100644
index 0000000..3345f36
--- /dev/null
+++ b/service/src/main/resources/init_quartz_postgres.sql
@@ -0,0 +1,203 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License.  You may obtain a copy of the License at
+--
+--   http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied.  See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+
+--
+-- In your Quartz properties file, you'll need to set
+-- org.quartz.jobStore.driverDelegateClass = 
org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
+
+drop table qrtz_fired_triggers;
+DROP TABLE QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE QRTZ_SCHEDULER_STATE;
+DROP TABLE QRTZ_LOCKS;
+drop table qrtz_simple_triggers;
+drop table qrtz_cron_triggers;
+drop table qrtz_simprop_triggers;
+DROP TABLE QRTZ_BLOB_TRIGGERS;
+drop table qrtz_triggers;
+drop table qrtz_job_details;
+drop table qrtz_calendars;
+
+CREATE TABLE qrtz_job_details
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
+    IS_DURABLE BOOL NOT NULL,
+    IS_NONCONCURRENT BOOL NOT NULL,
+    IS_UPDATE_DATA BOOL NOT NULL,
+    REQUESTS_RECOVERY BOOL NOT NULL,
+    JOB_DATA BYTEA NULL,
+    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+
+CREATE TABLE qrtz_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    NEXT_FIRE_TIME BIGINT NULL,
+    PREV_FIRE_TIME BIGINT NULL,
+    PRIORITY INTEGER NULL,
+    TRIGGER_STATE VARCHAR(16) NOT NULL,
+    TRIGGER_TYPE VARCHAR(8) NOT NULL,
+    START_TIME BIGINT NOT NULL,
+    END_TIME BIGINT NULL,
+    CALENDAR_NAME VARCHAR(200) NULL,
+    MISFIRE_INSTR SMALLINT NULL,
+    JOB_DATA BYTEA NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+       REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+
+CREATE TABLE qrtz_simple_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    REPEAT_COUNT BIGINT NOT NULL,
+    REPEAT_INTERVAL BIGINT NOT NULL,
+    TIMES_TRIGGERED BIGINT NOT NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+       REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_cron_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    CRON_EXPRESSION VARCHAR(120) NOT NULL,
+    TIME_ZONE_ID VARCHAR(80),
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+       REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_simprop_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 BOOL NULL,
+    BOOL_PROP_2 BOOL NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_blob_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    BLOB_DATA BYTEA NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_calendars
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    CALENDAR_NAME  VARCHAR(200) NOT NULL,
+    CALENDAR BYTEA NOT NULL,
+    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+
+
+CREATE TABLE qrtz_paused_trigger_grps
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_GROUP  VARCHAR(200) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_fired_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    ENTRY_ID VARCHAR(95) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    FIRED_TIME BIGINT NOT NULL,
+    SCHED_TIME BIGINT NOT NULL,
+    PRIORITY INTEGER NOT NULL,
+    STATE VARCHAR(16) NOT NULL,
+    JOB_NAME VARCHAR(200) NULL,
+    JOB_GROUP VARCHAR(200) NULL,
+    IS_NONCONCURRENT BOOL NULL,
+    REQUESTS_RECOVERY BOOL NULL,
+    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+
+CREATE TABLE qrtz_scheduler_state
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    LAST_CHECKIN_TIME BIGINT NOT NULL,
+    CHECKIN_INTERVAL BIGINT NOT NULL,
+    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+
+CREATE TABLE qrtz_locks
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    LOCK_NAME  VARCHAR(40) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+
+create index idx_qrtz_j_req_recovery on 
qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
+
+create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
+create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
+create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
+create index idx_qrtz_t_n_state on 
qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_n_g_state on 
qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_next_fire_time on 
qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st on 
qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_misfire on 
qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st_misfire on 
qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+create index idx_qrtz_t_nft_st_misfire_grp on 
qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+create index idx_qrtz_ft_trig_inst_name on 
qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
+create index idx_qrtz_ft_inst_job_req_rcvry on 
qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_ft_j_g on 
qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_ft_t_g on 
qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);
+
+
+commit;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/main/resources/quartz.properties
----------------------------------------------------------------------
diff --git a/service/src/main/resources/quartz.properties 
b/service/src/main/resources/quartz.properties
index ebfd3d2..aaf24fe 100644
--- a/service/src/main/resources/quartz.properties
+++ b/service/src/main/resources/quartz.properties
@@ -22,7 +22,7 @@ org.quartz.scheduler.instanceName=spring-boot-quartz
 org.quartz.scheduler.instanceId=AUTO
 org.quartz.threadPool.threadCount=5
 org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
-org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
 org.quartz.jobStore.useProperties=true
 org.quartz.jobStore.misfireThreshold=60000
 org.quartz.jobStore.tablePrefix=QRTZ_

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/test/java/org/apache/griffin/core/config/EclipseLinkJpaConfigForTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/config/EclipseLinkJpaConfigForTest.java
 
b/service/src/test/java/org/apache/griffin/core/config/EclipseLinkJpaConfigForTest.java
new file mode 100644
index 0000000..49b7436
--- /dev/null
+++ 
b/service/src/test/java/org/apache/griffin/core/config/EclipseLinkJpaConfigForTest.java
@@ -0,0 +1,39 @@
+package org.apache.griffin.core.config;
+
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
+import 
org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
+import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
+import org.springframework.transaction.jta.JtaTransactionManager;
+
+import javax.sql.DataSource;
+import java.util.HashMap;
+import java.util.Map;
+
+@TestConfiguration
+@ComponentScan("org.apache.griffin.core")
+public class EclipseLinkJpaConfigForTest extends JpaBaseConfiguration {
+    protected EclipseLinkJpaConfigForTest(DataSource ds, JpaProperties 
properties,
+                                          
ObjectProvider<JtaTransactionManager> jtm,
+                                          
ObjectProvider<TransactionManagerCustomizers> tmc) {
+        super(ds, properties, jtm, tmc);
+    }
+
+    @Override
+    protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
+        return new EclipseLinkJpaVendorAdapter();
+    }
+
+    @Override
+    protected Map<String, Object> getVendorProperties() {
+        Map<String, Object> map = new HashMap<>();
+        map.put(PersistenceUnitProperties.WEAVING, "false");
+        map.put(PersistenceUnitProperties.DDL_GENERATION, 
"create-or-extend-tables");
+        return map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/test/java/org/apache/griffin/core/config/PropertiesConfigTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/config/PropertiesConfigTest.java
 
b/service/src/test/java/org/apache/griffin/core/config/PropertiesConfigTest.java
index c3e35b6..2b8b2cf 100644
--- 
a/service/src/test/java/org/apache/griffin/core/config/PropertiesConfigTest.java
+++ 
b/service/src/test/java/org/apache/griffin/core/config/PropertiesConfigTest.java
@@ -33,7 +33,6 @@ import java.util.Properties;
 import static org.junit.Assert.assertEquals;
 
 @RunWith(SpringRunner.class)
-//@TestPropertySource("classpath")
 public class PropertiesConfigTest {
 
     @TestConfiguration

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/test/java/org/apache/griffin/core/job/JobInstanceBeanRepoTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/job/JobInstanceBeanRepoTest.java
 
b/service/src/test/java/org/apache/griffin/core/job/JobInstanceBeanRepoTest.java
index cdfbe45..658bd16 100644
--- 
a/service/src/test/java/org/apache/griffin/core/job/JobInstanceBeanRepoTest.java
+++ 
b/service/src/test/java/org/apache/griffin/core/job/JobInstanceBeanRepoTest.java
@@ -19,6 +19,8 @@ under the License.
 
 package org.apache.griffin.core.job;
 
+import org.apache.griffin.core.config.EclipseLinkJpaConfigForTest;
+import org.apache.griffin.core.job.entity.GriffinJob;
 import org.apache.griffin.core.job.entity.JobInstanceBean;
 import org.apache.griffin.core.job.entity.LivySessionStates;
 import org.apache.griffin.core.job.repo.JobInstanceRepo;
@@ -32,15 +34,20 @@ import 
org.springframework.context.annotation.PropertySource;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
+import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import java.util.List;
 
+import static org.apache.griffin.core.job.entity.LivySessionStates.State.*;
+import static org.apache.griffin.core.job.entity.LivySessionStates.State.busy;
+import static 
org.apache.griffin.core.job.entity.LivySessionStates.State.running;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertEquals;
 
 @RunWith(SpringRunner.class)
 @PropertySource("classpath:application.properties")
+@ContextConfiguration(classes = {EclipseLinkJpaConfigForTest.class})
 @DataJpaTest
 public class JobInstanceBeanRepoTest {
 
@@ -55,18 +62,18 @@ public class JobInstanceBeanRepoTest {
         setEntityManager();
     }
 
-//    @Test
-//    public void testFindByJobIdWithPageable() {
-//        Pageable pageRequest = new PageRequest(0, 10, Sort.Direction.DESC, 
"timestamp");
-//        List<JobInstanceBean> instances = jobInstanceRepo.findByJobId(1L, 
pageRequest);
-//        assertThat(instances.size()).isEqualTo(1);
-//        assertEquals(instances.get(0).getAppId(), "appId1");
-//    }
+    @Test
+    public void testFindByJobIdWithPageable() {
+        Pageable pageRequest = new PageRequest(0, 10, Sort.Direction.DESC, 
"tms");
+        List<JobInstanceBean> instances = jobInstanceRepo.findByJobId(1L, 
pageRequest);
+        assertThat(instances.size()).isEqualTo(3);
+    }
 
 
     @Test
     public void testFindByActiveState() {
-        List<JobInstanceBean> list = jobInstanceRepo.findByActiveState();
+        LivySessionStates.State[] states = {starting, not_started, recovering, 
idle, running, busy};
+        List<JobInstanceBean> list = jobInstanceRepo.findByActiveState(states);
         assertThat(list.size()).isEqualTo(1);
     }
 
@@ -74,12 +81,17 @@ public class JobInstanceBeanRepoTest {
 
 
     private void setEntityManager() {
+        GriffinJob job = new GriffinJob(1L, "jobName", "qName", "qGroup", 
false);
+        entityManager.persistAndFlush(job);
         JobInstanceBean instance1 = new JobInstanceBean(1L,  
LivySessionStates.State.success,
                 "appId1", "http://domain.com/uri1";, 
System.currentTimeMillis(),System.currentTimeMillis());
         JobInstanceBean instance2 = new JobInstanceBean(2L,  
LivySessionStates.State.error,
                 "appId2", "http://domain.com/uri2";, 
System.currentTimeMillis(),System.currentTimeMillis());
         JobInstanceBean instance3 = new JobInstanceBean(2L,  
LivySessionStates.State.starting,
                 "appId3", "http://domain.com/uri3";, 
System.currentTimeMillis(),System.currentTimeMillis());
+        instance1.setGriffinJob(job);
+        instance2.setGriffinJob(job);
+        instance3.setGriffinJob(job);
         entityManager.persistAndFlush(instance1);
         entityManager.persistAndFlush(instance2);
         entityManager.persistAndFlush(instance3);

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/4aab9d53/service/src/test/java/org/apache/griffin/core/job/JobInstanceTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/job/JobInstanceTest.java 
b/service/src/test/java/org/apache/griffin/core/job/JobInstanceTest.java
index cec6965..ec180d6 100644
--- a/service/src/test/java/org/apache/griffin/core/job/JobInstanceTest.java
+++ b/service/src/test/java/org/apache/griffin/core/job/JobInstanceTest.java
@@ -21,6 +21,7 @@ package org.apache.griffin.core.job;
 
 import org.apache.griffin.core.job.entity.*;
 import org.apache.griffin.core.job.repo.GriffinJobRepo;
+import org.apache.griffin.core.job.repo.JobInstanceRepo;
 import org.apache.griffin.core.job.repo.JobScheduleRepo;
 import org.apache.griffin.core.measure.entity.GriffinMeasure;
 import org.apache.griffin.core.measure.repo.GriffinMeasureRepo;
@@ -29,6 +30,7 @@ import org.apache.griffin.core.util.PropertiesUtil;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Matchers;
+import org.mockito.Mock;
 import org.quartz.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -65,7 +67,7 @@ public class JobInstanceTest {
             return PropertiesUtil.getProperties(path, new 
ClassPathResource(path));
         }
 
-        @Bean
+        @Bean(name = "schedulerFactoryBean")
         public SchedulerFactoryBean factoryBean() {
             return new SchedulerFactoryBean();
         }
@@ -79,6 +81,9 @@ public class JobInstanceTest {
     private Properties appConfProps;
 
     @MockBean
+    private JobInstanceRepo instanceRepo;
+
+    @MockBean
     private SchedulerFactoryBean factory;
 
     @MockBean

Reply via email to