You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sw...@apache.org on 2015/11/17 00:53:59 UTC

ambari git commit: AMBARI-13753. Refactor code that caches stale entity references. Fixed broken test. (swagle)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 b790b136c -> ea4e31ad2


AMBARI-13753. Refactor code that caches stale entity references. Fixed broken test. (swagle)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ea4e31ad
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ea4e31ad
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ea4e31ad

Branch: refs/heads/branch-2.1
Commit: ea4e31ad2b3207e251ebb4b4aee5fe41e4dcb4d1
Parents: b790b13
Author: Siddharth Wagle <sw...@hortonworks.com>
Authored: Mon Nov 16 15:53:43 2015 -0800
Committer: Siddharth Wagle <sw...@hortonworks.com>
Committed: Mon Nov 16 15:53:43 2015 -0800

----------------------------------------------------------------------
 .../actionmanager/ActionDBAccessorImpl.java     |   2 +-
 .../orm/entities/ClusterServiceEntity.java      |   4 +-
 .../HostComponentDesiredStateEntity.java        |   1 -
 .../orm/entities/HostComponentStateEntity.java  |   2 +-
 .../ambari/server/orm/entities/HostEntity.java  |   4 +-
 .../ServiceComponentDesiredStateEntity.java     |   4 +-
 .../server/state/ServiceComponentImpl.java      | 107 ++++---
 .../apache/ambari/server/state/ServiceImpl.java | 107 ++++---
 .../svccomphost/ServiceComponentHostImpl.java   | 280 +++++++++++++------
 .../server/upgrade/AbstractUpgradeCatalog.java  |   5 +
 .../server/upgrade/UpgradeCatalog150.java       |  29 +-
 .../server/upgrade/UpgradeCatalog210.java       |  72 ++---
 .../server/orm/dao/AlertDefinitionDAOTest.java  |  30 +-
 .../server/testing/DBInconsistencyTests.java    | 176 ++++++++++++
 .../server/upgrade/UpgradeCatalog150Test.java   |  12 +-
 .../server/upgrade/UpgradeCatalog210Test.java   |   8 +-
 16 files changed, 626 insertions(+), 217 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
index 99c327f..32e8754 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionDBAccessorImpl.java
@@ -145,7 +145,7 @@ public class ActionDBAccessorImpl implements ActionDBAccessor {
   public List<Stage> getAllStages(long requestId) {
     List<StageEntity> stageEntities = stageDAO.findByRequestId(requestId);
     List<Stage> stages = new ArrayList<>(stageEntities.size());
-    for( StageEntity stageEntity : stageEntities ){
+    for (StageEntity stageEntity : stageEntities ){
       stages.add(stageFactory.createExisting(stageEntity));
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
index eade294..320c1be 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
@@ -49,10 +49,10 @@ public class ClusterServiceEntity {
   @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false)
   private ClusterEntity clusterEntity;
 
-  @OneToOne(mappedBy = "clusterServiceEntity", cascade = CascadeType.ALL)
+  @OneToOne(mappedBy = "clusterServiceEntity")
   private ServiceDesiredStateEntity serviceDesiredStateEntity;
 
-  @OneToMany(mappedBy = "clusterServiceEntity", cascade = CascadeType.ALL)
+  @OneToMany(mappedBy = "clusterServiceEntity")
   private Collection<ServiceComponentDesiredStateEntity> serviceComponentDesiredStateEntities;
 
   public Long getClusterId() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
index 101aea1..b57a467 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
@@ -95,7 +95,6 @@ public class HostComponentDesiredStateEntity {
   @Column(name = "admin_state", nullable = true, insertable = true, updatable = true)
   private HostComponentAdminState adminState;
 
-  @ManyToOne(cascade = CascadeType.PERSIST)
   @JoinColumns({
       @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false),
       @JoinColumn(name = "service_name", referencedColumnName = "service_name", nullable = false),

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java
index ee8e7d6..f1af9b0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java
@@ -108,7 +108,7 @@ public class HostComponentStateEntity {
   @JoinColumn(name = "current_stack_id", unique = false, nullable = false, insertable = true, updatable = true)
   private StackEntity currentStack;
 
-  @ManyToOne(cascade = CascadeType.PERSIST)
+  @ManyToOne
   @JoinColumns({
       @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false),
       @JoinColumn(name = "service_name", referencedColumnName = "service_name", nullable = false),

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java
index 42f7777..502c060 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java
@@ -123,10 +123,10 @@ public class HostEntity implements Comparable<HostEntity> {
   @Lob
   private String hostAttributes = "";
 
-  @OneToMany(mappedBy = "hostEntity", cascade = {CascadeType.REMOVE, CascadeType.PERSIST})
+  @OneToMany(mappedBy = "hostEntity")
   private Collection<HostComponentDesiredStateEntity> hostComponentDesiredStateEntities;
 
-  @OneToMany(mappedBy = "hostEntity", cascade = {CascadeType.REMOVE, CascadeType.PERSIST})
+  @OneToMany(mappedBy = "hostEntity")
   private Collection<HostComponentStateEntity> hostComponentStateEntities;
 
   @OneToMany(mappedBy = "hostEntity", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
index c39ecc4..bda2543 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
@@ -66,10 +66,10 @@ public class ServiceComponentDesiredStateEntity {
   @JoinColumns({@javax.persistence.JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false), @JoinColumn(name = "service_name", referencedColumnName = "service_name", nullable = false)})
   private ClusterServiceEntity clusterServiceEntity;
 
-  @OneToMany(mappedBy = "serviceComponentDesiredStateEntity", cascade = CascadeType.ALL)
+  @OneToMany(mappedBy = "serviceComponentDesiredStateEntity")
   private Collection<HostComponentStateEntity> hostComponentStateEntities;
 
-  @OneToMany(mappedBy = "serviceComponentDesiredStateEntity", cascade = CascadeType.ALL)
+  @OneToMany(mappedBy = "serviceComponentDesiredStateEntity")
   private Collection<HostComponentDesiredStateEntity> hostComponentDesiredStateEntities;
 
   public Long getClusterId() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java
index 6150011..8673f8f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentImpl.java
@@ -59,6 +59,7 @@ public class ServiceComponentImpl implements ServiceComponent {
   private final Service service;
   private final ReadWriteLock clusterGlobalLock;
   private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
+  private final String componentName;
   private final boolean isClientComponent;
   private final boolean isMasterComponent;
   private final boolean isVersionAdvertised;
@@ -74,6 +75,7 @@ public class ServiceComponentImpl implements ServiceComponent {
   @Inject
   private AmbariMetaInfo ambariMetaInfo;
   private ServiceComponentDesiredStateEntity desiredStateEntity;
+  private ServiceComponentDesiredStateEntityPK desiredStateEntityPK;
   private Map<String, ServiceComponentHost> hostComponents;
 
   /**
@@ -88,10 +90,12 @@ public class ServiceComponentImpl implements ServiceComponent {
     injector.injectMembers(this);
     clusterGlobalLock = service.getClusterGlobalLock();
     this.service = service;
-    desiredStateEntity = new ServiceComponentDesiredStateEntity();
+    desiredStateEntity = new ServiceComponentDesiredStateEntity(  );
     desiredStateEntity.setComponentName(componentName);
     desiredStateEntity.setDesiredState(State.INIT);
-
+    desiredStateEntity.setServiceName(service.getName());
+    desiredStateEntity.setClusterId(service.getClusterId());
+    desiredStateEntityPK = getDesiredStateEntityPK(desiredStateEntity);
     setDesiredStackVersion(service.getDesiredStackVersion());
 
     hostComponents = new HashMap<String, ServiceComponentHost>();
@@ -111,6 +115,7 @@ public class ServiceComponentImpl implements ServiceComponent {
           + ", componentName=" + componentName
           + ", stackInfo=" + stackId.getStackId());
     }
+    this.componentName = componentName;
   }
 
   @AssistedInject
@@ -121,6 +126,7 @@ public class ServiceComponentImpl implements ServiceComponent {
     clusterGlobalLock = service.getClusterGlobalLock();
     this.service = service;
     desiredStateEntity = serviceComponentDesiredStateEntity;
+    this.componentName = serviceComponentDesiredStateEntity.getComponentName();
 
     hostComponents = new HashMap<String, ServiceComponentHost>();
     for (HostComponentStateEntity hostComponentStateEntity : desiredStateEntity.getHostComponentStateEntities()) {
@@ -148,7 +154,7 @@ public class ServiceComponentImpl implements ServiceComponent {
     try {
       ComponentInfo compInfo = ambariMetaInfo.getComponent(
           stackId.getStackName(), stackId.getStackVersion(), service.getName(),
-          getName());
+          componentName);
       isClientComponent = compInfo.isClient();
       isMasterComponent = compInfo.isMaster();
       isVersionAdvertised = compInfo.isVersionAdvertised();
@@ -157,10 +163,12 @@ public class ServiceComponentImpl implements ServiceComponent {
           + " not recognized in stack info"
           + ", clusterName=" + service.getCluster().getClusterName()
           + ", serviceName=" + service.getName()
-          + ", componentName=" + getName()
+          + ", componentName=" + componentName
           + ", stackInfo=" + stackId.getStackId());
     }
 
+    desiredStateEntityPK = getDesiredStateEntityPK(desiredStateEntity);
+
     persisted = true;
   }
 
@@ -171,7 +179,15 @@ public class ServiceComponentImpl implements ServiceComponent {
 
   @Override
   public String getName() {
-    return desiredStateEntity.getComponentName();
+    ServiceComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+    if (desiredStateEntity != null) {
+      return desiredStateEntity.getComponentName();
+    } else {
+      LOG.warn("Trying to fetch a member from an entity object that may " +
+        "have been previously deleted, serviceName = " + getServiceName() + ", " +
+        "componentName = " + componentName);
+    }
+    return null;
   }
 
   @Override
@@ -263,8 +279,7 @@ public class ServiceComponentImpl implements ServiceComponent {
   }
 
   @Override
-  public ServiceComponentHost addServiceComponentHost(
-      String hostName) throws AmbariException {
+  public ServiceComponentHost addServiceComponentHost(String hostName) throws AmbariException {
     clusterGlobalLock.writeLock().lock();
     try {
       readWriteLock.writeLock().lock();
@@ -327,10 +342,19 @@ public class ServiceComponentImpl implements ServiceComponent {
   public State getDesiredState() {
     readWriteLock.readLock().lock();
     try {
-      return desiredStateEntity.getDesiredState();
+      ServiceComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        return desiredStateEntity.getDesiredState();
+      } else {
+        LOG.warn("Trying to fetch a member from an entity object that may " +
+          "have been previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + componentName);
+      }
+
     } finally {
       readWriteLock.readLock().unlock();
     }
+    return null;
   }
 
   @Override
@@ -345,8 +369,15 @@ public class ServiceComponentImpl implements ServiceComponent {
             + ", oldDesiredState=" + getDesiredState() + ", newDesiredState="
             + state);
       }
-      desiredStateEntity.setDesiredState(state);
-      saveIfPersisted();
+      ServiceComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        desiredStateEntity.setDesiredState(state);
+        saveIfPersisted();
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + (service != null ? service.getName() : ""));
+      }
+
     } finally {
       readWriteLock.writeLock().unlock();
     }
@@ -356,7 +387,7 @@ public class ServiceComponentImpl implements ServiceComponent {
   public StackId getDesiredStackVersion() {
     readWriteLock.readLock().lock();
     try {
-      StackEntity stackEntity = desiredStateEntity.getDesiredStack();
+      StackEntity stackEntity = getDesiredStateEntity().getDesiredStack();
       if (null != stackEntity) {
         return new StackId(stackEntity.getStackName(),
             stackEntity.getStackVersion());
@@ -382,10 +413,17 @@ public class ServiceComponentImpl implements ServiceComponent {
       }
 
       StackEntity stackEntity = stackDAO.find(stack.getStackName(),
-          stack.getStackVersion());
+        stack.getStackVersion());
+
+      ServiceComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        desiredStateEntity.setDesiredStack(stackEntity);
+        saveIfPersisted();
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + (service != null ? service.getName() : ""));
+      }
 
-      desiredStateEntity.setDesiredStack(stackEntity);
-      saveIfPersisted();
     } finally {
       readWriteLock.writeLock().unlock();
     }
@@ -474,7 +512,9 @@ public class ServiceComponentImpl implements ServiceComponent {
           clusterWriteLockAcquired = false;
 
           refresh();
-          service.refresh();
+          // There refresh calls are no longer needed with cached references
+          // not used on getters/setters
+          // service.refresh();
           persisted = true;
         } else {
           saveIfPersisted();
@@ -511,9 +551,7 @@ public class ServiceComponentImpl implements ServiceComponent {
         pk.setComponentName(getName());
         pk.setClusterId(getClusterId());
         pk.setServiceName(getServiceName());
-        // TODO: desiredStateEntity is assigned in unway, may be a bug
-        desiredStateEntity = serviceComponentDesiredStateDAO.findByPK(pk);
-        serviceComponentDesiredStateDAO.refresh(desiredStateEntity);
+        serviceComponentDesiredStateDAO.refresh(getDesiredStateEntity());
       }
     } finally {
       readWriteLock.writeLock().unlock();
@@ -580,8 +618,7 @@ public class ServiceComponentImpl implements ServiceComponent {
 
   @Override
   @Transactional
-  public void deleteAllServiceComponentHosts()
-      throws AmbariException {
+  public void deleteAllServiceComponentHosts() throws AmbariException {
     clusterGlobalLock.writeLock().lock();
     try {
       readWriteLock.writeLock().lock();
@@ -616,8 +653,7 @@ public class ServiceComponentImpl implements ServiceComponent {
   }
 
   @Override
-  public void deleteServiceComponentHosts(String hostname)
-      throws AmbariException {
+  public void deleteServiceComponentHosts(String hostname) throws AmbariException {
     clusterGlobalLock.writeLock().lock();
     try {
       readWriteLock.writeLock().lock();
@@ -644,8 +680,6 @@ public class ServiceComponentImpl implements ServiceComponent {
     } finally {
       clusterGlobalLock.writeLock().unlock();
     }
-
-
   }
 
   @Override
@@ -667,18 +701,11 @@ public class ServiceComponentImpl implements ServiceComponent {
     } finally {
       clusterGlobalLock.writeLock().unlock();
     }
-
-
   }
 
   @Transactional
   protected void removeEntities() throws AmbariException {
-    ServiceComponentDesiredStateEntityPK pk = new ServiceComponentDesiredStateEntityPK();
-    pk.setClusterId(getClusterId());
-    pk.setComponentName(getName());
-    pk.setServiceName(getServiceName());
-
-    serviceComponentDesiredStateDAO.removeByPK(pk);
+    serviceComponentDesiredStateDAO.remove(getDesiredStateEntity());
   }
 
   private int getSCHCountByState(State state) {
@@ -703,4 +730,20 @@ public class ServiceComponentImpl implements ServiceComponent {
     return hostComponents.size();
   }
 
+  // Refresh cached reference after ever setter
+  private ServiceComponentDesiredStateEntity getDesiredStateEntity() {
+    if (isPersisted()) {
+      desiredStateEntity = serviceComponentDesiredStateDAO.findByPK(desiredStateEntityPK);
+    }
+    return desiredStateEntity;
+  }
+
+  private ServiceComponentDesiredStateEntityPK getDesiredStateEntityPK(ServiceComponentDesiredStateEntity desiredStateEntity) {
+    ServiceComponentDesiredStateEntityPK pk = new ServiceComponentDesiredStateEntityPK();
+    pk.setClusterId(desiredStateEntity.getClusterId());
+    pk.setComponentName(desiredStateEntity.getComponentName());
+    pk.setServiceName(desiredStateEntity.getServiceName());
+
+    return pk;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
index bbe2f62..74f9e02 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
@@ -18,13 +18,12 @@
 
 package org.apache.ambari.server.state;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.ProvisionException;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import com.google.inject.persist.Transactional;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ServiceComponentNotFoundException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -39,34 +38,34 @@ import org.apache.ambari.server.orm.dao.ServiceConfigDAO;
 import org.apache.ambari.server.orm.dao.ServiceDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
-import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity;
 import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntityPK;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
 import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntity;
+import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntityPK;
 import org.apache.ambari.server.orm.entities.StackEntity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.ProvisionException;
-import com.google.inject.assistedinject.Assisted;
-import com.google.inject.assistedinject.AssistedInject;
-import com.google.inject.persist.Transactional;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 
 public class ServiceImpl implements Service {
   private final ReadWriteLock clusterGlobalLock;
   private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
-
+  // Cached entity has only 1 getter for name
   private ClusterServiceEntity serviceEntity;
   private ServiceDesiredStateEntity serviceDesiredStateEntity;
+  private ServiceDesiredStateEntityPK serviceDesiredStateEntityPK;
+  private ClusterServiceEntityPK serviceEntityPK;
 
-  private static final Logger LOG =
-      LoggerFactory.getLogger(ServiceImpl.class);
+  private static final Logger LOG = LoggerFactory.getLogger(ServiceImpl.class);
 
   private volatile boolean persisted = false;
   private final Cluster cluster;
@@ -108,8 +107,14 @@ public class ServiceImpl implements Service {
     injector.injectMembers(this);
     clusterGlobalLock = cluster.getClusterGlobalLock();
     serviceEntity = new ClusterServiceEntity();
+    serviceEntity.setClusterId(cluster.getClusterId());
     serviceEntity.setServiceName(serviceName);
     serviceDesiredStateEntity = new ServiceDesiredStateEntity();
+    serviceDesiredStateEntity.setServiceName(serviceName);
+    serviceDesiredStateEntity.setClusterId(cluster.getClusterId());
+
+    serviceDesiredStateEntityPK = getServiceDesiredStateEntityPK(serviceDesiredStateEntity);
+    serviceEntityPK = getServiceEntityPK(serviceEntity);
 
     serviceDesiredStateEntity.setClusterServiceEntity(serviceEntity);
     serviceEntity.setServiceDesiredStateEntity(serviceDesiredStateEntity);
@@ -138,6 +143,8 @@ public class ServiceImpl implements Service {
 
     //TODO check for null states?
     serviceDesiredStateEntity = serviceEntity.getServiceDesiredStateEntity();
+    serviceDesiredStateEntityPK = getServiceDesiredStateEntityPK(serviceDesiredStateEntity);
+    serviceEntityPK = getServiceEntityPK(serviceEntity);
 
     components = new HashMap<String, ServiceComponent>();
 
@@ -210,8 +217,7 @@ public class ServiceImpl implements Service {
   }
 
   @Override
-  public void addServiceComponent(ServiceComponent component)
-      throws AmbariException {
+  public void addServiceComponent(ServiceComponent component) throws AmbariException {
     clusterGlobalLock.writeLock().lock();
     try {
       readWriteLock.writeLock().lock();
@@ -241,8 +247,8 @@ public class ServiceImpl implements Service {
   }
 
   @Override
-  public ServiceComponent addServiceComponent(
-      String serviceComponentName) throws AmbariException {
+  public ServiceComponent addServiceComponent(String serviceComponentName)
+      throws AmbariException {
     clusterGlobalLock.writeLock().lock();
     try {
       readWriteLock.writeLock().lock();
@@ -291,7 +297,7 @@ public class ServiceImpl implements Service {
   public State getDesiredState() {
     readWriteLock.readLock().lock();
     try {
-      return serviceDesiredStateEntity.getDesiredState();
+      return getServiceDesiredStateEntity().getDesiredState();
     } finally {
       readWriteLock.readLock().unlock();
     }
@@ -306,9 +312,9 @@ public class ServiceImpl implements Service {
             + cluster.getClusterName() + ", clusterId="
             + cluster.getClusterId() + ", serviceName=" + getName()
             + ", oldDesiredState=" + getDesiredState() + ", newDesiredState="
-            + state);
+            + state + ", persisted = " + isPersisted());
       }
-      serviceDesiredStateEntity.setDesiredState(state);
+      getServiceDesiredStateEntity().setDesiredState(state);
       saveIfPersisted();
     } finally {
       readWriteLock.writeLock().unlock();
@@ -319,7 +325,7 @@ public class ServiceImpl implements Service {
   public SecurityState getSecurityState() {
     readWriteLock.readLock().lock();
     try {
-      return serviceDesiredStateEntity.getSecurityState();
+      return getServiceDesiredStateEntity().getSecurityState();
     } finally {
       readWriteLock.readLock().unlock();
     }
@@ -340,7 +346,7 @@ public class ServiceImpl implements Service {
             + ", oldDesiredSecurityState=" + getSecurityState()
             + ", newDesiredSecurityState=" + securityState);
       }
-      serviceDesiredStateEntity.setSecurityState(securityState);
+      getServiceDesiredStateEntity().setSecurityState(securityState);
       saveIfPersisted();
     } finally {
       readWriteLock.writeLock().unlock();
@@ -351,7 +357,7 @@ public class ServiceImpl implements Service {
   public StackId getDesiredStackVersion() {
     readWriteLock.readLock().lock();
     try {
-      StackEntity desiredStackEntity = serviceDesiredStateEntity.getDesiredStack();
+      StackEntity desiredStackEntity = getServiceDesiredStateEntity().getDesiredStack();
       if( null != desiredStackEntity ) {
         return new StackId(desiredStackEntity);
       } else {
@@ -375,7 +381,7 @@ public class ServiceImpl implements Service {
       }
 
       StackEntity stackEntity = stackDAO.find(stack.getStackName(), stack.getStackVersion());
-      serviceDesiredStateEntity.setDesiredStack(stackEntity);
+      getServiceDesiredStateEntity().setDesiredStack(stackEntity);
       saveIfPersisted();
     } finally {
       readWriteLock.writeLock().unlock();
@@ -454,7 +460,9 @@ public class ServiceImpl implements Service {
         if (!persisted) {
           persistEntities();
           refresh();
-          cluster.refresh();
+          // There refresh calls are no longer needed with cached references
+          // not used on getters/setters
+          // cluster.refresh();
           persisted = true;
 
           // publish the service installed event
@@ -548,8 +556,8 @@ public class ServiceImpl implements Service {
   @Transactional
   void deleteAllServiceConfigs() throws AmbariException {
     LOG.info("Deleting all serviceconfigs for service"
-        + ", clusterName=" + cluster.getClusterName()
-        + ", serviceName=" + getName());
+      + ", clusterName=" + cluster.getClusterName()
+      + ", serviceName=" + getName());
     
     List<ServiceConfigEntity> serviceConfigEntities = serviceConfigDAO.findByService(cluster.getClusterId(), getName());
 
@@ -678,6 +686,8 @@ public class ServiceImpl implements Service {
 
   @Transactional
   protected void removeEntities() throws AmbariException {
+    serviceDesiredStateDAO.removeByPK(serviceDesiredStateEntityPK);
+
     ClusterServiceEntityPK pk = new ClusterServiceEntityPK();
     pk.setClusterId(getClusterId());
     pk.setServiceName(getName());
@@ -689,7 +699,7 @@ public class ServiceImpl implements Service {
   public void setMaintenanceState(MaintenanceState state) {
     readWriteLock.writeLock().lock();
     try {
-      serviceDesiredStateEntity.setMaintenanceState(state);
+      getServiceDesiredStateEntity().setMaintenanceState(state);
       saveIfPersisted();
 
       // broadcast the maintenance mode change
@@ -702,6 +712,35 @@ public class ServiceImpl implements Service {
 
   @Override
   public MaintenanceState getMaintenanceState() {
-    return serviceDesiredStateEntity.getMaintenanceState();
+    return getServiceDesiredStateEntity().getMaintenanceState();
+  }
+
+  private ClusterServiceEntity getServiceEntity() {
+    if (isPersisted()) {
+      serviceEntity = clusterServiceDAO.findByPK(serviceEntityPK);
+    }
+    return serviceEntity;
+  }
+
+  private ClusterServiceEntityPK getServiceEntityPK(ClusterServiceEntity serviceEntity) {
+    ClusterServiceEntityPK pk = new ClusterServiceEntityPK();
+    pk.setClusterId(serviceEntity.getClusterId());
+    pk.setServiceName(serviceEntity.getServiceName());
+    return pk;
+  }
+
+  private ServiceDesiredStateEntityPK getServiceDesiredStateEntityPK(ServiceDesiredStateEntity serviceDesiredStateEntity) {
+    ServiceDesiredStateEntityPK pk = new ServiceDesiredStateEntityPK();
+    pk.setClusterId(serviceDesiredStateEntity.getClusterId());
+    pk.setServiceName(serviceDesiredStateEntity.getServiceName());
+    return pk;
+  }
+
+  // Refresh the cached reference on setters
+  private ServiceDesiredStateEntity getServiceDesiredStateEntity() {
+    if (isPersisted()) {
+      serviceDesiredStateEntity = serviceDesiredStateDAO.findByPK(serviceDesiredStateEntityPK);
+    }
+    return serviceDesiredStateEntity;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index 7b1c6ca..21daed0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -93,8 +93,6 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   private static final Logger LOG =
       LoggerFactory.getLogger(ServiceComponentHostImpl.class);
 
-  // FIXME need more debug logs
-
   private final ReadWriteLock clusterGlobalLock;
   private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
   private final Lock readLock = readWriteLock.readLock();
@@ -142,7 +140,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   @Inject
   private StackDAO stackDAO;
 
-  // TODO : caching the JPA entities here causes issues if they become stale and get re-merged.
+  // Only used when object state is not persisted
   private HostComponentStateEntity stateEntity;
   private HostComponentDesiredStateEntity desiredStateEntity;
 
@@ -151,6 +149,11 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
    */
   private final HostComponentDesiredStateEntityPK desiredStateEntityPK;
 
+  /**
+   * Cache the generated id for host component state for fast lookups.
+   */
+  private Long hostComponentStateId;
+
   private long lastOpStartTime;
   private long lastOpEndTime;
   private long lastOpLastUpdateTime;
@@ -784,6 +787,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     this.stateEntity = stateEntity;
 
     desiredStateEntityPK = getHostComponentDesiredStateEntityPK(desiredStateEntity);
+    hostComponentStateId = stateEntity.getId();
 
     //TODO implement State Machine init as now type choosing is hardcoded in above code
     if (serviceComponent.isClientComponent()) {
@@ -816,8 +820,17 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     writeLock.lock();
     try {
       stateMachine.setCurrentState(state);
-      getStateEntity().setCurrentState(state);
-      saveIfPersisted();
+      HostComponentStateEntity stateEntity = getStateEntity();
+      if (stateEntity != null) {
+        getStateEntity().setCurrentState(state);
+        saveIfPersisted();
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
+
     } finally {
       writeLock.unlock();
     }
@@ -827,18 +840,35 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public String getVersion() {
     readLock.lock();
     try {
-      return stateEntity.getVersion();
+      HostComponentStateEntity stateEntity = getStateEntity();
+      if (stateEntity != null) {
+        return stateEntity.getVersion();
+      } else {
+        LOG.warn("Trying to fetch a member from an entity object that may " +
+          "have been previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
     } finally {
       readLock.unlock();
     }
+    return null;
   }
 
   @Override
   public void setVersion(String version) {
     writeLock.lock();
     try {
-      getStateEntity().setVersion(version);
-      saveIfPersisted();
+      HostComponentStateEntity stateEntity = getStateEntity();
+      if (stateEntity != null) {
+        getStateEntity().setVersion(version);
+        saveIfPersisted();
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
     } finally {
       writeLock.unlock();
     }
@@ -848,18 +878,37 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public SecurityState getSecurityState() {
     readLock.lock();
     try {
-      return stateEntity.getSecurityState();
+      HostComponentStateEntity stateEntity = getStateEntity();
+      if (stateEntity != null) {
+        return getStateEntity().getSecurityState();
+      } else {
+        LOG.warn("Trying to fetch a member from an entity object that may " +
+          "have been previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
+
     } finally {
       readLock.unlock();
     }
+    return null;
   }
 
   @Override
   public void setSecurityState(SecurityState securityState) {
     writeLock.lock();
     try {
-      getStateEntity().setSecurityState(securityState);
-      saveIfPersisted();
+      HostComponentStateEntity stateEntity = getStateEntity();
+      if (stateEntity != null) {
+        getStateEntity().setSecurityState(securityState);
+        saveIfPersisted();
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
+
     } finally {
       writeLock.unlock();
     }
@@ -869,10 +918,20 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public SecurityState getDesiredSecurityState() {
     readLock.lock();
     try {
-      return desiredStateEntity.getSecurityState();
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        return getDesiredStateEntity().getSecurityState();
+      } else {
+        LOG.warn("Trying to fetch a member from an entity object that may " +
+          "have been previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
+
     } finally {
       readLock.unlock();
     }
+    return null;
   }
 
   @Override
@@ -903,8 +962,17 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public void setUpgradeState(UpgradeState upgradeState) {
     writeLock.lock();
     try {
-      getStateEntity().setUpgradeState(upgradeState);
-      saveIfPersisted();
+      HostComponentStateEntity stateEntity = getStateEntity();
+      if (stateEntity != null) {
+        stateEntity.setUpgradeState(upgradeState);
+        saveIfPersisted();
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
+
     } finally {
       writeLock.unlock();
     }
@@ -933,7 +1001,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
               + " current state"
               + ", serviceComponentName=" + getServiceComponentName()
               + ", hostName=" + getHostName()
-              + ", currentState=" + oldState
+            + ", currentState=" + oldState
               + ", eventType=" + event.getType()
               + ", event=" + event);
           throw e;
@@ -1083,8 +1151,17 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
 
     writeLock.lock();
     try {
-      getStateEntity().setCurrentStack(stackEntity);
-      saveIfPersisted();
+      HostComponentStateEntity stateEntity = getStateEntity();
+      if (stateEntity != null) {
+        stateEntity.setCurrentStack(stackEntity);
+        saveIfPersisted();
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
+
     } finally {
       writeLock.unlock();
     }
@@ -1094,18 +1171,36 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public State getDesiredState() {
     readLock.lock();
     try {
-      return desiredStateEntity.getDesiredState();
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        return desiredStateEntity.getDesiredState();
+      } else {
+        LOG.warn("Trying to fetch a member from an entity object that may " +
+          "have been previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
+
     } finally {
       readLock.unlock();
     }
+    return null;
   }
 
   @Override
   public void setDesiredState(State state) {
     writeLock.lock();
     try {
-      getDesiredStateEntity().setDesiredState(state);
-      saveIfPersisted();
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        desiredStateEntity.setDesiredState(state);
+        saveIfPersisted();
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() +
+          "hostName = " + getHostName());
+      }
     } finally {
       writeLock.unlock();
     }
@@ -1115,23 +1210,36 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public StackId getDesiredStackVersion() {
     readLock.lock();
     try {
-      StackEntity desiredStackEntity = desiredStateEntity.getDesiredStack();
-      return new StackId(desiredStackEntity.getStackName(),
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        StackEntity desiredStackEntity = desiredStateEntity.getDesiredStack();
+        return new StackId(desiredStackEntity.getStackName(),
           desiredStackEntity.getStackVersion());
+      } else {
+        LOG.warn("Trying to fetch a member from an entity object that may " +
+          "have been previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() + ", " +
+          "hostName = " + getHostName());
+      }
+
     } finally {
       readLock.unlock();
     }
+    return null;
   }
 
   @Override
   public void setDesiredStackVersion(StackId stackId) {
     writeLock.lock();
     try {
-      StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
           stackId.getStackVersion());
 
-      getDesiredStateEntity().setDesiredStack(stackEntity);
-      saveIfPersisted();
+        desiredStateEntity.setDesiredStack(stackEntity);
+        saveIfPersisted();
+      }
     } finally {
       writeLock.unlock();
     }
@@ -1141,23 +1249,36 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public HostComponentAdminState getComponentAdminState() {
     readLock.lock();
     try {
-      HostComponentAdminState adminState = desiredStateEntity.getAdminState();
-      if (adminState == null && !serviceComponent.isClientComponent()
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        HostComponentAdminState adminState = desiredStateEntity.getAdminState();
+        if (adminState == null && !serviceComponent.isClientComponent()
           && !serviceComponent.isMasterComponent()) {
-        adminState = HostComponentAdminState.INSERVICE;
+          adminState = HostComponentAdminState.INSERVICE;
+        }
+        return adminState;
       }
-      return adminState;
+
     } finally {
       readLock.unlock();
     }
+    return null;
   }
 
   @Override
   public void setComponentAdminState(HostComponentAdminState attribute) {
     writeLock.lock();
     try {
-      getDesiredStateEntity().setAdminState(attribute);
-      saveIfPersisted();
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        desiredStateEntity.setAdminState(attribute);
+        saveIfPersisted();
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() +
+          "hostName = " + getHostName());
+      }
     } finally {
       writeLock.unlock();
     }
@@ -1223,7 +1344,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
           getStackVersion()).append(", state=").append(getState()).append(
           ", securityState=").append(getSecurityState()).append(
           ", desiredSecurityState=").append(getDesiredSecurityState()).append(
-          " }");
+        " }");
     } finally {
       readLock.unlock();
     }
@@ -1269,8 +1390,11 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
 
           // these should still be done with the internal lock
           refresh();
-          host.refresh();
-          serviceComponent.refresh();
+          // There refresh calls are no longer needed with cached references
+          // not used on getters/setters
+          // NOTE: Refreshing parents is a bad pattern.
+          //host.refresh();
+          //serviceComponent.refresh();
 
           // publish the service component installed event
           StackId stackId = getDesiredStackVersion();
@@ -1315,6 +1439,11 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     hostComponentStateDAO.create(stateEntity);
     hostComponentDesiredStateDAO.create(desiredStateEntity);
 
+    HostComponentStateEntity stateEntity = hostComponentStateDAO.findByIndex(serviceComponent.getClusterId(),
+      serviceComponent.getServiceName(), serviceComponent.getName(), hostEntity.getHostId());
+
+    hostComponentStateId = stateEntity.getId();
+
     serviceComponentDesiredStateDAO.merge(serviceComponentDesiredStateEntity);
     hostDAO.merge(hostEntity);
   }
@@ -1362,7 +1491,6 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     }
   }
 
-
   @Override
   public void delete() {
     boolean fireRemovalEvent = false;
@@ -1415,21 +1543,17 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   @Transactional
   protected void removeEntities() {
     HostComponentStateEntity stateEntity = getStateEntity();
-    if (null != stateEntity) {
-      hostComponentStateDAO.remove(stateEntity);
-    }
-
-    HostComponentDesiredStateEntityPK desiredPK = new HostComponentDesiredStateEntityPK();
-    desiredPK.setClusterId(desiredStateEntity.getClusterId());
-    desiredPK.setComponentName(desiredStateEntity.getComponentName());
-    desiredPK.setServiceName(desiredStateEntity.getServiceName());
-    desiredPK.setHostId(desiredStateEntity.getHostId());
+    if (stateEntity != null) {
+      // make sure that the state entities are removed from the associated (detached) host entity
+      // Also refresh before delete
+      stateEntity.getHostEntity().removeHostComponentStateEntity(stateEntity);
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      desiredStateEntity.getHostEntity().removeHostComponentDesiredStateEntity(desiredStateEntity);
 
-    hostComponentDesiredStateDAO.removeByPK(desiredPK);
+      hostComponentDesiredStateDAO.remove(desiredStateEntity);
 
-    // make sure that the state entities are removed from the associated (detached) host entity
-    stateEntity.getHostEntity().removeHostComponentStateEntity(stateEntity);
-    desiredStateEntity.getHostEntity().removeHostComponentDesiredStateEntity(desiredStateEntity);
+      hostComponentStateDAO.remove(stateEntity);
+    }
   }
 
   @Override
@@ -1500,13 +1624,20 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public void setMaintenanceState(MaintenanceState state) {
     writeLock.lock();
     try {
-      getDesiredStateEntity().setMaintenanceState(state);
-      saveIfPersisted();
-
-      // broadcast the maintenance mode change
-      MaintenanceModeEvent event = new MaintenanceModeEvent(state, this);
-      eventPublisher.publish(event);
-
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        desiredStateEntity.setMaintenanceState(state);
+        saveIfPersisted();
+
+        // broadcast the maintenance mode change
+        MaintenanceModeEvent event = new MaintenanceModeEvent(state, this);
+        eventPublisher.publish(event);
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() +
+          ", hostName = " + getHostName());
+      }
     } finally {
       writeLock.unlock();
     }
@@ -1516,7 +1647,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public MaintenanceState getMaintenanceState() {
     readLock.lock();
     try {
-      return desiredStateEntity.getMaintenanceState();
+      return getDesiredStateEntity().getMaintenanceState();
     } finally {
       readLock.unlock();
     }
@@ -1546,7 +1677,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public boolean isRestartRequired() {
     readLock.lock();
     try {
-      return desiredStateEntity.isRestartRequired();
+      return getDesiredStateEntity().isRestartRequired();
     } finally {
       readLock.unlock();
     }
@@ -1556,9 +1687,18 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   public void setRestartRequired(boolean restartRequired) {
     writeLock.lock();
     try {
-      getDesiredStateEntity().setRestartRequired(restartRequired);
-      saveIfPersisted();
-      helper.invalidateStaleConfigsCache(this);
+      HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+      if (desiredStateEntity != null) {
+        desiredStateEntity.setRestartRequired(restartRequired);
+        saveIfPersisted();
+        helper.invalidateStaleConfigsCache(this);
+      } else {
+        LOG.warn("Setting a member on an entity object that may have been " +
+          "previously deleted, serviceName = " + getServiceName() + ", " +
+          "componentName = " + getServiceComponentName() +
+          ", hostName = " + getHostName());
+      }
+
     } finally {
       writeLock.unlock();
     }
@@ -1570,7 +1710,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
     LOG.info("Creating new repository version " + stackId.getStackName() + "-" + version);
 
     StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
-        stackId.getStackVersion());
+      stackId.getStackVersion());
 
     // Ensure that the version provided is part of the Stack.
     // E.g., version 2.3.0.0 is part of HDP 2.3, so is 2.3.0.0-1234
@@ -1645,23 +1785,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
    */
   private HostComponentStateEntity getStateEntity() {
     if (isPersisted()) {
-      final HostEntity host = hostDAO.findById(stateEntity.getHostId());
-      Collection<HostComponentStateEntity> hostComponentStateEntities = host.getHostComponentStateEntities();
-      for (HostComponentStateEntity hostComponentStateEntity : hostComponentStateEntities) {
-        String serviceName = stateEntity.getServiceName();
-        String componentName = stateEntity.getComponentName();
-        Long clusterId = stateEntity.getClusterId();
-        Long hostId = stateEntity.getHostId();
-
-        if (StringUtils.equals(hostComponentStateEntity.getServiceName(), serviceName)
-            && StringUtils.equals(hostComponentStateEntity.getComponentName(), componentName)
-            && hostComponentStateEntity.getClusterId() == clusterId
-            && hostComponentStateEntity.getHostId() == hostId) {
-
-          stateEntity = hostComponentStateEntity;
-          return stateEntity;
-        }
-      }
+      stateEntity = hostComponentStateDAO.findById(hostComponentStateId);
     }
 
     return stateEntity;

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java
index 194ac7d..30e4151 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java
@@ -221,6 +221,11 @@ public abstract class AbstractUpgradeCatalog implements UpgradeCatalog {
       try {
         func.run();
         entityManager.getTransaction().commit();
+        // This is required because some of the  entities actively managed by
+        // the persistence context will remain unaware of the actual changes
+        // occurring at the database level. Some UpgradeCatalogs perform
+        // update / delete using CriteriaBuilder directly.
+        entityManager.getEntityManagerFactory().getCache().evictAll();
       } catch (Exception e) {
         LOG.error("Error in transaction ", e);
         if (entityManager.getTransaction().isActive()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
index f6b388f..00baf28 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
@@ -645,13 +645,16 @@ public class UpgradeCatalog150 extends AbstractUpgradeCatalog {
 
       ClusterServiceEntity clusterServiceEntity = clusterServiceDAO.findByPK(pk);
 
-
       final ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity = new ServiceComponentDesiredStateEntity();
+      serviceComponentDesiredStateEntity.setClusterId(clusterEntity.getClusterId());
       serviceComponentDesiredStateEntity.setComponentName("HISTORYSERVER");
       serviceComponentDesiredStateEntity.setDesiredStack(clusterEntity.getDesiredStack());
       serviceComponentDesiredStateEntity.setDesiredState(jtServiceComponentDesiredState);
       serviceComponentDesiredStateEntity.setClusterServiceEntity(clusterServiceEntity);
       serviceComponentDesiredStateEntity.setHostComponentDesiredStateEntities(new ArrayList<HostComponentDesiredStateEntity>());
+      serviceComponentDesiredStateEntity.setHostComponentStateEntities(new ArrayList<HostComponentStateEntity>());
+
+      serviceComponentDesiredStateDAO.create(serviceComponentDesiredStateEntity);
 
       final HostEntity host = hostDao.findByName(jtHostname);
       if (host == null) {
@@ -662,36 +665,42 @@ public class UpgradeCatalog150 extends AbstractUpgradeCatalog {
       stateEntity.setHostEntity(host);
       stateEntity.setCurrentState(jtCurrState);
       stateEntity.setCurrentStack(clusterEntity.getDesiredStack());
+      stateEntity.setClusterId(clusterEntity.getClusterId());
 
       final HostComponentDesiredStateEntity desiredStateEntity = new HostComponentDesiredStateEntity();
       desiredStateEntity.setDesiredState(jtHostComponentDesiredState);
       desiredStateEntity.setDesiredStack(clusterEntity.getDesiredStack());
+      desiredStateEntity.setClusterId(clusterEntity.getClusterId());
 
       persistComponentEntities(stateEntity, desiredStateEntity, serviceComponentDesiredStateEntity);
     }
   }
 
-  private void persistComponentEntities(HostComponentStateEntity stateEntity, HostComponentDesiredStateEntity desiredStateEntity, ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity) {
+  private void persistComponentEntities(HostComponentStateEntity stateEntity,
+                                        HostComponentDesiredStateEntity desiredStateEntity,
+                                        ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity) {
     ServiceComponentDesiredStateDAO serviceComponentDesiredStateDAO = injector.getInstance(ServiceComponentDesiredStateDAO.class);
     HostComponentStateDAO hostComponentStateDAO = injector.getInstance(HostComponentStateDAO.class);
     HostComponentDesiredStateDAO hostComponentDesiredStateDAO = injector.getInstance(HostComponentDesiredStateDAO.class);
     HostDAO hostDAO = injector.getInstance(HostDAO.class);
 
     HostEntity hostEntity = stateEntity.getHostEntity();
-    hostEntity.addHostComponentStateEntity(stateEntity);
-    hostEntity.addHostComponentDesiredStateEntity(desiredStateEntity);
 
+    desiredStateEntity.setHostEntity(hostEntity);
+    desiredStateEntity.setServiceComponentDesiredStateEntity(serviceComponentDesiredStateEntity);
     serviceComponentDesiredStateEntity.getHostComponentDesiredStateEntities().add(desiredStateEntity);
+    hostComponentDesiredStateDAO.create(desiredStateEntity);
 
-    desiredStateEntity.setServiceComponentDesiredStateEntity(serviceComponentDesiredStateEntity);
-    desiredStateEntity.setHostEntity(hostEntity);
-    stateEntity.setServiceComponentDesiredStateEntity(serviceComponentDesiredStateEntity);
     stateEntity.setHostEntity(hostEntity);
-
+    stateEntity.setServiceComponentDesiredStateEntity(serviceComponentDesiredStateEntity);
+    serviceComponentDesiredStateEntity.getHostComponentStateEntities().add(stateEntity);
     hostComponentStateDAO.create(stateEntity);
-    hostComponentDesiredStateDAO.create(desiredStateEntity);
 
-    serviceComponentDesiredStateDAO.create(serviceComponentDesiredStateEntity);
+    serviceComponentDesiredStateDAO.merge(serviceComponentDesiredStateEntity);
+
+    hostEntity.addHostComponentDesiredStateEntity(desiredStateEntity);
+    hostEntity.addHostComponentStateEntity(stateEntity);
+
     hostDAO.merge(hostEntity);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
index 52079cf..ba8267c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
@@ -1150,44 +1150,44 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
           executeInTransaction(new Runnable() {
             @Override
             public void run() {
-              ServiceComponentDesiredStateDAO dao = injector.getInstance(ServiceComponentDesiredStateDAO.class);
-              ServiceComponentDesiredStateEntityPK entityPK = new ServiceComponentDesiredStateEntityPK();
-              entityPK.setClusterId(cluster.getClusterId());
-              entityPK.setServiceName("STORM");
-              entityPK.setComponentName("STORM_REST_API");
-              ServiceComponentDesiredStateEntity entity = dao.findByPK(entityPK);
-              if (entity != null) {
-                EntityManager em = getEntityManagerProvider().get();
-                CriteriaBuilder cb = em.getCriteriaBuilder();
-
-                try {
-                  LOG.info("Deleting STORM_REST_API service component.");
-                  CriteriaDelete<HostComponentStateEntity> hcsDelete = cb.createCriteriaDelete(HostComponentStateEntity.class);
-                  CriteriaDelete<HostComponentDesiredStateEntity> hcdDelete = cb.createCriteriaDelete(HostComponentDesiredStateEntity.class);
-                  CriteriaDelete<ServiceComponentDesiredStateEntity> scdDelete = cb.createCriteriaDelete(ServiceComponentDesiredStateEntity.class);
-
-                  Root<HostComponentStateEntity> hcsRoot = hcsDelete.from(HostComponentStateEntity.class);
-                  Root<HostComponentDesiredStateEntity> hcdRoot = hcdDelete.from(HostComponentDesiredStateEntity.class);
-                  Root<ServiceComponentDesiredStateEntity> scdRoot = scdDelete.from(ServiceComponentDesiredStateEntity.class);
-
-                  hcsDelete.where(cb.equal(hcsRoot.get("componentName"), "STORM_REST_API"));
-                  hcdDelete.where(cb.equal(hcdRoot.get("componentName"), "STORM_REST_API"));
-                  scdDelete.where(cb.equal(scdRoot.get("componentName"), "STORM_REST_API"));
-
-                  em.createQuery(hcsDelete).executeUpdate();
-                  em.createQuery(hcdDelete).executeUpdate();
-                  em.createQuery(scdDelete).executeUpdate();
-                } catch (Exception e) {
-                  LOG.warn("Error deleting STORM_REST_API service component. " +
-                    "This could result in issue with ambari server start. " +
-                    "Please make sure the STORM_REST_API component is deleted " +
-                    "from the database by running following commands:\n" +
-                    "delete from hostcomponentdesiredstate where component_name='STORM_REST_API';\n" +
-                    "delete from hostcomponentstate where component_name='STORM_REST_API';\n" +
-                    "delete from servicecomponentdesiredstate where component_name='STORM_REST_API';\n", e);
-                }
+            ServiceComponentDesiredStateDAO dao = injector.getInstance(ServiceComponentDesiredStateDAO.class);
+            ServiceComponentDesiredStateEntityPK entityPK = new ServiceComponentDesiredStateEntityPK();
+            entityPK.setClusterId(cluster.getClusterId());
+            entityPK.setServiceName("STORM");
+            entityPK.setComponentName("STORM_REST_API");
+            ServiceComponentDesiredStateEntity entity = dao.findByPK(entityPK);
+            if (entity != null) {
+              EntityManager em = getEntityManagerProvider().get();
+              CriteriaBuilder cb = em.getCriteriaBuilder();
+
+              try {
+                LOG.info("Deleting STORM_REST_API service component.");
+                CriteriaDelete<HostComponentStateEntity> hcsDelete = cb.createCriteriaDelete(HostComponentStateEntity.class);
+                CriteriaDelete<HostComponentDesiredStateEntity> hcdDelete = cb.createCriteriaDelete(HostComponentDesiredStateEntity.class);
+                CriteriaDelete<ServiceComponentDesiredStateEntity> scdDelete = cb.createCriteriaDelete(ServiceComponentDesiredStateEntity.class);
+
+                Root<HostComponentStateEntity> hcsRoot = hcsDelete.from(HostComponentStateEntity.class);
+                Root<HostComponentDesiredStateEntity> hcdRoot = hcdDelete.from(HostComponentDesiredStateEntity.class);
+                Root<ServiceComponentDesiredStateEntity> scdRoot = scdDelete.from(ServiceComponentDesiredStateEntity.class);
+
+                hcsDelete.where(cb.equal(hcsRoot.get("componentName"), "STORM_REST_API"));
+                hcdDelete.where(cb.equal(hcdRoot.get("componentName"), "STORM_REST_API"));
+                scdDelete.where(cb.equal(scdRoot.get("componentName"), "STORM_REST_API"));
+
+                em.createQuery(hcsDelete).executeUpdate();
+                em.createQuery(hcdDelete).executeUpdate();
+                em.createQuery(scdDelete).executeUpdate();
+              } catch (Exception e) {
+                LOG.warn("Error deleting STORM_REST_API service component. " +
+                  "This could result in issue with ambari server start. " +
+                  "Please make sure the STORM_REST_API component is deleted " +
+                  "from the database by running following commands:\n" +
+                  "delete from hostcomponentdesiredstate where component_name='STORM_REST_API';\n" +
+                  "delete from hostcomponentstate where component_name='STORM_REST_API';\n" +
+                  "delete from servicecomponentdesiredstate where component_name='STORM_REST_API';\n", e);
               }
             }
+            }
           });
         }
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index 95209d4..d0ad386 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -18,17 +18,9 @@
 
 package org.apache.ambari.server.orm.dao;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.TimeZone;
-import java.util.UUID;
-
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
 import com.google.inject.persist.UnitOfWork;
 import org.apache.ambari.server.controller.RootServiceResponseFactory;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
@@ -50,10 +42,19 @@ import org.apache.ambari.server.state.alert.SourceType;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.persist.PersistService;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
 /**
  * Tests {@link AlertDefinitionDAO} for interacting with
@@ -75,6 +76,7 @@ public class AlertDefinitionDAOTest {
    */
   @Before
   public void setup() throws Exception {
+//    LoggerFactory.getLogger("eclipselink").
     injector = Guice.createInjector(new InMemoryDefaultTestModule());
     injector.getInstance(GuiceJpaInitializer.class);
     injector.getInstance(UnitOfWork.class).begin();

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/test/java/org/apache/ambari/server/testing/DBInconsistencyTests.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/testing/DBInconsistencyTests.java b/ambari-server/src/test/java/org/apache/ambari/server/testing/DBInconsistencyTests.java
new file mode 100644
index 0000000..05a75b3
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/testing/DBInconsistencyTests.java
@@ -0,0 +1,176 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ */
+package org.apache.ambari.server.testing;
+
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.OrmTestHelper;
+import org.apache.ambari.server.orm.dao.ClusterDAO;
+import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
+import org.apache.ambari.server.orm.dao.ServiceComponentDesiredStateDAO;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
+import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
+import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentFactory;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.ServiceComponentHostFactory;
+import org.apache.ambari.server.state.ServiceFactory;
+import org.apache.ambari.server.state.State;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import java.util.Collection;
+import java.util.List;
+
+public class DBInconsistencyTests {
+
+  private static Logger LOG = LoggerFactory.getLogger(DBInconsistencyTests.class);
+
+  @Inject
+  private Injector injector;
+  @Inject
+  private OrmTestHelper helper;
+  @Inject
+  private Clusters clusters;
+  @Inject
+  private ServiceFactory serviceFactory;
+  @Inject
+  private ServiceComponentFactory serviceComponentFactory;
+  @Inject
+  private ServiceComponentHostFactory serviceComponentHostFactory;
+  @Inject
+  private HostComponentDesiredStateDAO hostComponentDesiredStateDAO;
+  @Inject
+  private ServiceComponentDesiredStateDAO serviceComponentDesiredStateDAO;
+  @Inject
+  private ClusterDAO clusterDAO;
+
+  @Before
+  public void setup() throws Exception {
+    injector = Guice.createInjector(new InMemoryDefaultTestModule());
+    injector.getInstance(GuiceJpaInitializer.class);
+    injector.injectMembers(this);
+  }
+
+  @After
+  public void teardown() {
+    injector.getInstance(PersistService.class).stop();
+  }
+
+  @Test
+  public void testOrphanedSCHDesiredEntityReAdd() throws Exception {
+    Long clusterId = helper.createCluster();
+    Assert.assertNotNull(clusterId);
+
+    Cluster cluster = clusters.getCluster(OrmTestHelper.CLUSTER_NAME);
+    Assert.assertNotNull(cluster);
+
+    helper.addHost(clusters, cluster, "h1");
+
+    helper.installHdfsService(cluster, serviceFactory,
+      serviceComponentFactory, serviceComponentHostFactory, "h1");
+
+    Collection<ServiceComponentHost> schList = clusters.getCluster(
+      OrmTestHelper.CLUSTER_NAME).getServiceComponentHosts("HDFS", "DATANODE");
+    Assert.assertNotNull(schList);
+
+    Collection<ServiceComponent> scList = cluster.getService("HDFS").getServiceComponents().values();
+    Assert.assertNotNull(schList);
+
+    cluster.deleteService("HDFS");
+
+    List<HostComponentDesiredStateEntity> hostComponentDesiredStateEntities =
+      hostComponentDesiredStateDAO.findAll();
+    Assert.assertTrue(hostComponentDesiredStateEntities == null ||
+      hostComponentDesiredStateEntities.isEmpty());
+
+    List<ServiceComponentDesiredStateEntity> serviceComponentDesiredStateEntities =
+      serviceComponentDesiredStateDAO.findAll();
+    Assert.assertTrue(serviceComponentDesiredStateEntities == null ||
+      serviceComponentDesiredStateEntities.isEmpty());
+
+    EntityManager em = helper.getEntityManager();
+    final EntityTransaction txn = em.getTransaction();
+
+    txn.begin();
+
+    for (ServiceComponentHost sch : schList) {
+      sch.setDesiredState(State.DISABLED);
+    }
+
+    for (ServiceComponent sc : scList) {
+      sc.setDesiredState(State.DISABLED);
+    }
+
+    txn.commit();
+
+    hostComponentDesiredStateEntities = hostComponentDesiredStateDAO.findAll();
+    Assert.assertTrue(hostComponentDesiredStateEntities == null || hostComponentDesiredStateEntities.isEmpty());
+
+    serviceComponentDesiredStateEntities = serviceComponentDesiredStateDAO.findAll();
+    Assert.assertTrue(serviceComponentDesiredStateEntities == null ||
+      serviceComponentDesiredStateEntities.isEmpty());
+  }
+
+  @Ignore // This non-functional in terms of actual code path
+  @Test
+  public void testRefreshInSameTxn() throws Exception {
+    Long clusterId = helper.createCluster();
+    Assert.assertNotNull(clusterId);
+
+    Cluster cluster = clusters.getCluster(OrmTestHelper.CLUSTER_NAME);
+    Assert.assertNotNull(cluster);
+
+    EntityManager em = helper.getEntityManager();
+    final EntityTransaction txn = em.getTransaction();
+
+    txn.begin();
+
+    ClusterEntity entity = clusterDAO.findById(clusterId);
+    entity.setProvisioningState(State.DISABLED);
+    clusterDAO.merge(entity);
+
+    Assert.assertEquals(State.DISABLED, entity.getProvisioningState());
+
+    entity = clusterDAO.findById(clusterId);
+
+    Assert.assertEquals(State.DISABLED, entity.getProvisioningState());
+
+    entity.setProvisioningState(State.INIT);
+
+    txn.commit();
+
+    entity = clusterDAO.findById(clusterId);
+
+    Assert.assertEquals(State.INIT, entity.getProvisioningState());
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog150Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog150Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog150Test.java
index 39dd815..4647815 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog150Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog150Test.java
@@ -28,12 +28,14 @@ import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.ClusterDAO;
 import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.KeyValueDAO;
+import org.apache.ambari.server.orm.dao.ServiceComponentDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
 import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity;
 import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
 import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
+import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
 import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.orm.entities.KeyValueEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
@@ -48,6 +50,9 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
 
+import java.util.ArrayList;
+import java.util.Collections;
+
 public class UpgradeCatalog150Test {
   private Injector injector;
   private final String CLUSTER_NAME = "c1";
@@ -140,7 +145,10 @@ public class UpgradeCatalog150Test {
     componentDesiredStateEntity.setComponentName("DATANODE");
     componentDesiredStateEntity.setDesiredStack(desiredStackEntity);
 
-    //componentDesiredStateDAO.create(componentDesiredStateEntity);
+    ServiceComponentDesiredStateDAO componentDesiredStateDAO =
+      injector.getInstance(ServiceComponentDesiredStateDAO.class);
+
+    componentDesiredStateDAO.create(componentDesiredStateEntity);
 
     HostComponentDesiredStateDAO hostComponentDesiredStateDAO =
       injector.getInstance(HostComponentDesiredStateDAO.class);
@@ -155,6 +163,8 @@ public class UpgradeCatalog150Test {
     hostComponentDesiredStateEntity.setServiceComponentDesiredStateEntity(componentDesiredStateEntity);
     hostComponentDesiredStateEntity.setHostEntity(hostEntity);
     hostComponentDesiredStateEntity.setDesiredStack(desiredStackEntity);
+    componentDesiredStateEntity.setHostComponentDesiredStateEntities(
+      Collections.singletonList(hostComponentDesiredStateEntity));
 
     hostComponentDesiredStateDAO.create(hostComponentDesiredStateEntity);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea4e31ad/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java
index 482ac38..c2889fe 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog210Test.java
@@ -577,6 +577,11 @@ public class UpgradeCatalog210Test {
     componentDesiredStateEntity.setComponentName("STORM_REST_API");
     componentDesiredStateEntity.setDesiredStack(desiredStackEntity);
 
+    ServiceComponentDesiredStateDAO componentDesiredStateDAO =
+      injector.getInstance(ServiceComponentDesiredStateDAO.class);
+
+    componentDesiredStateDAO.create(componentDesiredStateEntity);
+
     HostComponentDesiredStateDAO hostComponentDesiredStateDAO =
       injector.getInstance(HostComponentDesiredStateDAO.class);
 
@@ -599,9 +604,6 @@ public class UpgradeCatalog210Test {
     UpgradeCatalog210 upgradeCatalog210 = injector.getInstance(UpgradeCatalog210.class);
     upgradeCatalog210.removeStormRestApiServiceComponent();
 
-    ServiceComponentDesiredStateDAO componentDesiredStateDAO =
-      injector.getInstance(ServiceComponentDesiredStateDAO.class);
-
     ServiceComponentDesiredStateEntityPK entityPK = new ServiceComponentDesiredStateEntityPK();
     entityPK.setClusterId(clusterEntity.getClusterId());
     entityPK.setServiceName("STORM");